makdoong2-team 2.3.2 → 3.0.1
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/README.md +4 -12
- package/agents/makdoong2-engineer.md +1 -0
- package/agents/makdoong2-planner.md +17 -61
- package/agents/makdoong2-team-leader.md +14 -4
- package/agents/makdoong2-verifier.md +6 -6
- package/assets/makdoong2-team.schema.json +0 -18
- package/bin/cli.js +27 -1
- package/bin/cli.ts +27 -1
- package/dist/agent-stage-config.d.ts +1 -1
- package/dist/agent-stage-config.js +0 -11
- package/dist/apply-patch-paths.d.ts +46 -0
- package/dist/apply-patch-paths.js +114 -0
- package/dist/config.d.ts +22 -9
- package/dist/config.js +61 -11
- package/dist/model-fallback-policy.js +0 -4
- package/dist/opencode-plugin.js +270 -356
- package/dist/poll-sub-session.d.ts +16 -1
- package/dist/poll-sub-session.js +76 -11
- package/dist/sub-session-registry.d.ts +74 -0
- package/dist/sub-session-registry.js +204 -0
- package/gates/stage-analysis-verify.sh +63 -5
- package/gates/stage4-dev-verify.sh +6 -6
- package/gates/verify.sh +0 -2
- package/opencode.json.example +0 -1
- package/package.json +1 -1
- package/scripts/gate-policy-test.sh +15 -14
- package/scripts/install-lib.mjs +1 -1
- package/scripts/install-lib.mts +1 -1
- package/scripts/model-policy.mjs +0 -4
- package/scripts/model-policy.mts +0 -4
- package/scripts/release.sh +13 -1
- package/scripts/run-tests.mts +4 -1
- package/scripts/state.sh +24 -2
- package/skills/_lib/load-secret.sh +15 -5
- package/src/hooks/session-start.sh +0 -1
- package/stages/01-planning.md +35 -54
- package/stages/02-requirements.md +53 -35
- package/stages/04-analysis.md +2 -2
- package/stages/05-worktree-dev.md +15 -0
- package/agents/makdoong2-researcher.md +0 -68
- package/dist/research-fanout.d.ts +0 -165
- package/dist/research-fanout.js +0 -341
- package/gates/stage3-scope-verify.sh +0 -69
- package/stages/03-scope.md +0 -81
package/dist/config.d.ts
CHANGED
|
@@ -33,13 +33,6 @@ export interface TimeoutConfig {
|
|
|
33
33
|
stall_escalate_threshold?: number;
|
|
34
34
|
}
|
|
35
35
|
export declare const DEFAULT_STALL_ESCALATE_THRESHOLD = 5;
|
|
36
|
-
export interface ResearchConfig {
|
|
37
|
-
/** Max research sub-sessions spawned simultaneously. Clamped to [1, 6]. */
|
|
38
|
-
max_parallel?: number;
|
|
39
|
-
/** Per-source wall-clock budget. Shorter than a substage on purpose — a source
|
|
40
|
-
* that cannot answer in this window is reported as failed, not waited on. */
|
|
41
|
-
timeout_minutes?: number;
|
|
42
|
-
}
|
|
43
36
|
export type LogLevel = "silent" | "error" | "warn" | "info" | "debug" | "trace";
|
|
44
37
|
export type LogMode = "stdin" | "file";
|
|
45
38
|
export interface LoggingConfig {
|
|
@@ -56,7 +49,6 @@ export interface Makdoong2Config {
|
|
|
56
49
|
threshold?: number;
|
|
57
50
|
};
|
|
58
51
|
timeout?: TimeoutConfig;
|
|
59
|
-
research?: ResearchConfig;
|
|
60
52
|
tmux?: TmuxConfigJson;
|
|
61
53
|
worktree?: {
|
|
62
54
|
extra_exclude?: string;
|
|
@@ -100,11 +92,32 @@ export declare function parseJsoncLoose(text: string): unknown;
|
|
|
100
92
|
* 서브세션의 permission 요청이 auto-reject 됐다.
|
|
101
93
|
* (install-lib 의 computeExternalDirPaths 가 그 값을 쓰는 쪽이다.)
|
|
102
94
|
*/
|
|
103
|
-
export declare function loadOpencodeExternalDirAllows(): string[];
|
|
95
|
+
export declare function loadOpencodeExternalDirAllows(diag?: (reason: string) => void): string[];
|
|
104
96
|
/** Resolve the five runtime path roots (JSON paths.* override → default).
|
|
105
97
|
*
|
|
106
98
|
* `skills` default is the opencode config dir (`${XDG_CONFIG_HOME:-$HOME/.config}/opencode/skills`)
|
|
107
99
|
* because scripts/install-lib.mjs deploys skill directories there, not into the
|
|
108
100
|
* package root. All other paths default to package-root subdirs.
|
|
109
101
|
*/
|
|
102
|
+
/**
|
|
103
|
+
* 플러그인이 **자기 자신을 실행하기 위해** 반드시 접근해야 하는 디렉토리들.
|
|
104
|
+
*
|
|
105
|
+
* 모든 substage 가 `bash <SCRIPTS_DIR>/state.sh` 를 호출하고, 게이트·stage spec·
|
|
106
|
+
* 리서치 스킬도 전부 opencode 설정 디렉토리(또는 패키지 루트) 아래에 있다.
|
|
107
|
+
* 이들은 **워크스페이스 밖**이므로 opencode 가 `external_directory` 승인을 묻는다
|
|
108
|
+
* (1.18 `ShellTool.ask` 는 bash 명령이 참조하는 디렉토리에도 발화한다).
|
|
109
|
+
*
|
|
110
|
+
* 종전에는 그 승인 근거가 설치 시 opencode.json 에 심어둔 시드 하나뿐이었다.
|
|
111
|
+
* 시드가 남지 않은 부분 설치에서는 서브에이전트가 **자기 상태 파일조차 읽지 못한 채**
|
|
112
|
+
* PERMISSION_STALL 로 죽었다 (GitHub #8). 파일 배포만 성공한 설치는 겉보기에 정상이라
|
|
113
|
+
* 원인 규명도 어려웠다.
|
|
114
|
+
*
|
|
115
|
+
* 그래서 플러그인이 자기 경로를 **설정과 무관하게** 스스로 허용한다. opencode.json
|
|
116
|
+
* 시드는 1차 방어로 그대로 두고(사용자가 직접 승인할 때의 UX), 이것이 2차 방어다 —
|
|
117
|
+
* 다른 하드룰들과 같은 이중 방어 구조다.
|
|
118
|
+
*
|
|
119
|
+
* 허용 범위를 넓히는 변경이 아니다: 여기 담기는 경로는 플러그인이 이미 자기 손으로
|
|
120
|
+
* 실행하고 있는 것들뿐이고, 워크스페이스·`/tmp`·홈 디렉토리는 포함되지 않는다.
|
|
121
|
+
*/
|
|
122
|
+
export declare function pluginOwnAllowPatterns(paths?: Required<PathsConfig>): string[];
|
|
110
123
|
export declare function resolvePaths(): Required<PathsConfig>;
|
package/dist/config.js
CHANGED
|
@@ -175,20 +175,36 @@ export function parseJsoncLoose(text) {
|
|
|
175
175
|
* 서브세션의 permission 요청이 auto-reject 됐다.
|
|
176
176
|
* (install-lib 의 computeExternalDirPaths 가 그 값을 쓰는 쪽이다.)
|
|
177
177
|
*/
|
|
178
|
-
export function loadOpencodeExternalDirAllows() {
|
|
178
|
+
export function loadOpencodeExternalDirAllows(diag) {
|
|
179
|
+
// 빈 배열로 끝나는 이유를 호출자가 알 수 있게 한다. 이 모듈은 logger 를 import
|
|
180
|
+
// 하지 못하므로(logger→config) 콜백으로 돌려준다. 같은 pid 의 두 플러그인 사본이
|
|
181
|
+
// 서로 다른 개수를 읽은 사례(issue #10: 7개→5개)에서 파일 부재였는지 파싱
|
|
182
|
+
// 실패였는지 키 부재였는지가 로그에 남지 않았다.
|
|
183
|
+
const file = join(configDir(), "opencode.json");
|
|
184
|
+
let raw;
|
|
179
185
|
try {
|
|
180
|
-
|
|
181
|
-
const oc = parseJsoncLoose(raw);
|
|
182
|
-
const ext = oc?.permission?.external_directory;
|
|
183
|
-
if (!ext || typeof ext !== "object")
|
|
184
|
-
return [];
|
|
185
|
-
return Object.entries(ext)
|
|
186
|
-
.filter(([, action]) => action === "allow")
|
|
187
|
-
.map(([pattern]) => pattern);
|
|
186
|
+
raw = readFileSync(file, "utf8");
|
|
188
187
|
}
|
|
189
|
-
catch {
|
|
190
|
-
|
|
188
|
+
catch (err) {
|
|
189
|
+
diag?.(`read failed: ${file}: ${err.message}`);
|
|
190
|
+
return []; // 부재 → 설정된 allow 없음
|
|
191
|
+
}
|
|
192
|
+
let oc;
|
|
193
|
+
try {
|
|
194
|
+
oc = parseJsoncLoose(raw);
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
diag?.(`parse failed: ${file} (${raw.length} bytes): ${err.message}`);
|
|
198
|
+
return []; // 파싱 실패 → 설정된 allow 없음
|
|
191
199
|
}
|
|
200
|
+
const ext = oc?.permission?.external_directory;
|
|
201
|
+
if (!ext || typeof ext !== "object") {
|
|
202
|
+
diag?.(`permission.external_directory absent: ${file}`);
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
205
|
+
return Object.entries(ext)
|
|
206
|
+
.filter(([, action]) => action === "allow")
|
|
207
|
+
.map(([pattern]) => pattern);
|
|
192
208
|
}
|
|
193
209
|
/** Resolve the five runtime path roots (JSON paths.* override → default).
|
|
194
210
|
*
|
|
@@ -196,6 +212,40 @@ export function loadOpencodeExternalDirAllows() {
|
|
|
196
212
|
* because scripts/install-lib.mjs deploys skill directories there, not into the
|
|
197
213
|
* package root. All other paths default to package-root subdirs.
|
|
198
214
|
*/
|
|
215
|
+
/**
|
|
216
|
+
* 플러그인이 **자기 자신을 실행하기 위해** 반드시 접근해야 하는 디렉토리들.
|
|
217
|
+
*
|
|
218
|
+
* 모든 substage 가 `bash <SCRIPTS_DIR>/state.sh` 를 호출하고, 게이트·stage spec·
|
|
219
|
+
* 리서치 스킬도 전부 opencode 설정 디렉토리(또는 패키지 루트) 아래에 있다.
|
|
220
|
+
* 이들은 **워크스페이스 밖**이므로 opencode 가 `external_directory` 승인을 묻는다
|
|
221
|
+
* (1.18 `ShellTool.ask` 는 bash 명령이 참조하는 디렉토리에도 발화한다).
|
|
222
|
+
*
|
|
223
|
+
* 종전에는 그 승인 근거가 설치 시 opencode.json 에 심어둔 시드 하나뿐이었다.
|
|
224
|
+
* 시드가 남지 않은 부분 설치에서는 서브에이전트가 **자기 상태 파일조차 읽지 못한 채**
|
|
225
|
+
* PERMISSION_STALL 로 죽었다 (GitHub #8). 파일 배포만 성공한 설치는 겉보기에 정상이라
|
|
226
|
+
* 원인 규명도 어려웠다.
|
|
227
|
+
*
|
|
228
|
+
* 그래서 플러그인이 자기 경로를 **설정과 무관하게** 스스로 허용한다. opencode.json
|
|
229
|
+
* 시드는 1차 방어로 그대로 두고(사용자가 직접 승인할 때의 UX), 이것이 2차 방어다 —
|
|
230
|
+
* 다른 하드룰들과 같은 이중 방어 구조다.
|
|
231
|
+
*
|
|
232
|
+
* 허용 범위를 넓히는 변경이 아니다: 여기 담기는 경로는 플러그인이 이미 자기 손으로
|
|
233
|
+
* 실행하고 있는 것들뿐이고, 워크스페이스·`/tmp`·홈 디렉토리는 포함되지 않는다.
|
|
234
|
+
*/
|
|
235
|
+
export function pluginOwnAllowPatterns(paths = resolvePaths()) {
|
|
236
|
+
const seen = new Set();
|
|
237
|
+
const out = [];
|
|
238
|
+
for (const dir of [paths.hooks, paths.gates, paths.scripts, paths.stages, paths.skills]) {
|
|
239
|
+
if (typeof dir !== "string" || dir.trim() === "")
|
|
240
|
+
continue;
|
|
241
|
+
const norm = dir.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
242
|
+
if (norm === "" || norm === "/" || seen.has(norm))
|
|
243
|
+
continue;
|
|
244
|
+
seen.add(norm);
|
|
245
|
+
out.push(`${norm}/**`);
|
|
246
|
+
}
|
|
247
|
+
return out;
|
|
248
|
+
}
|
|
199
249
|
export function resolvePaths() {
|
|
200
250
|
const p = loadConfig().paths ?? {};
|
|
201
251
|
const root = packageRoot();
|
|
@@ -74,10 +74,6 @@ export const POLICIES = {
|
|
|
74
74
|
fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
|
|
75
75
|
},
|
|
76
76
|
// Research fan-out worker — one session per source, spawned in parallel.
|
|
77
|
-
"makdoong2-researcher": {
|
|
78
|
-
primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
|
|
79
|
-
fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
|
|
80
|
-
},
|
|
81
77
|
"makdoong2-planner": {
|
|
82
78
|
primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
|
|
83
79
|
fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
|