@uzysjung/agent-harness 26.167.0 → 26.169.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/README.ko.md +2 -2
- package/README.md +2 -2
- package/dist/{chunk-KVXCTS6D.js → chunk-SU2RUN2W.js} +116 -88
- package/dist/chunk-SU2RUN2W.js.map +1 -0
- package/dist/index.js +1643 -966
- package/dist/index.js.map +1 -1
- package/dist/trust-tier-drift.js +5 -2
- package/dist/trust-tier-drift.js.map +1 -1
- package/package.json +1 -1
- package/templates/CLAUDE.md +7 -0
- package/templates/mcp.json +2 -8
- package/templates/rules/ship-checklist.md +2 -2
- package/templates/skills/audit-harness-fit/SKILL.md +15 -4
- package/templates/skills/audit-harness-fit/references/apply.md +18 -0
- package/templates/skills/audit-harness-fit/references/audit.md +16 -3
- package/templates/skills/audit-harness-fit/references/verification.md +7 -0
- package/templates/skills/chatgpt-delegate/SKILL.md +221 -0
- package/templates/skills/external-model-consult/SKILL.md +82 -40
- package/templates/skills/external-model-consult/references/direct-calls.md +23 -14
- package/templates/skills/external-model-consult/references/model-evidence.md +156 -0
- package/templates/skills/external-model-consult/scripts/codex-ask.sh +4 -3
- package/templates/skills/external-model-consult/scripts/gemini-ask.sh +3 -3
- package/templates/skills/gemini-delegate/SKILL.md +223 -0
- package/templates/skills/genspark-delegate/SKILL.md +283 -0
- package/templates/skills/model-orchestration/SKILL.md +5 -0
- package/templates/skills/multi-model-debate/SKILL.md +187 -0
- package/templates/skills/multi-model-debate/agents/openai.yaml +4 -0
- package/templates/skills/multi-model-debate/references/adapters.md +143 -0
- package/templates/skills/multi-model-debate/references/evaluation.md +80 -0
- package/templates/skills/multi-model-debate/references/prompts.md +87 -0
- package/templates/skills/multi-model-debate/references/research.md +171 -0
- package/templates/track-mcp-map.tsv +3 -1
- package/dist/chunk-KVXCTS6D.js.map +0 -1
package/README.ko.md
CHANGED
|
@@ -173,7 +173,7 @@ your-project/
|
|
|
173
173
|
| `project-management` | PM 업무 | 없음 |
|
|
174
174
|
| `growth-marketing` | 그로스·콘텐츠 마케팅 | 없음 (`marketingskills` 선택 가능) |
|
|
175
175
|
|
|
176
|
-
MCP 서버도 함께 들어간다. 모든 트랙에 `context7`(최신 라이브러리 문서)가 들어가고, 웹 트랙(`csr-*`, `ssr-*`, `full`)에는 Google 사용 통계를 끈 `chrome-devtools`가 더해진다. `csr-*`와 `ssr-htmx` 트랙에는 `railway-mcp-server`(Railway 원격 서버 — 처음 쓸 때 로그인한다)가, `csr-supabase`에는 `supabase
|
|
176
|
+
MCP 서버도 함께 들어간다. 모든 트랙에 `context7`(최신 라이브러리 문서)가 들어가고, 웹 트랙(`csr-*`, `ssr-*`, `full`)에는 Google 사용 통계를 끈 `chrome-devtools`가 더해진다. `csr-*`와 `ssr-htmx` 트랙에는 `railway-mcp-server`(Railway 원격 서버 — 처음 쓸 때 로그인한다)가, `csr-supabase`에는 `supabase`(Supabase 원격 서버 — 처음 쓸 때 로그인한다)가 더해진다. `full`은 둘 다 받는다. `ssr-nextjs`에서는 Railway MCP가 기본이 아니고, 직접 고르면 들어간다. Vercel·GitHub 공식 원격 서버(`vercel`, `github-mcp`)는 미리 체크되지 않는다 — `--with`로 더한다. 서버마다 위저드 3단계에 한 줄씩 보이고, 체크를 풀거나 `--without <이름>`(예: `--without context7`)을 주면 `.mcp.json`·Codex·OpenCode 에서 빠진다.
|
|
177
177
|
|
|
178
178
|
미리 체크되지는 않지만 3단계나 `--with <id>`로 더할 수 있는 것도 있다.
|
|
179
179
|
|
|
@@ -198,7 +198,7 @@ MCP 서버도 함께 들어간다. 모든 트랙에 `context7`(최신 라이브
|
|
|
198
198
|
|
|
199
199
|
`update`는 하네스가 설치한 것을 새 버전으로 바꾸고, 새 버전에 추가된 것을 넣고, 없어진 하네스 파일(훅 스크립트, `.mcp.json`의 서버, `AGENTS.md`의 하네스 절 등)을 되살린다. `--without`으로 일부러 뺀 항목은 계속 빠져 있고, 고르지 않은 도구는 설치하지 않는다. `update --only skills`처럼 한 묶음만 업데이트할 수도 있다.
|
|
200
200
|
|
|
201
|
-
터미널에서 `uninstall`을 실행하면 무엇을 지울지(도구 하나, 고른 항목, 전부) 고를 수 있고, `--dry-run`을 붙이면 지우기 전에 계획을 먼저 보여 준다. 전부 지울
|
|
201
|
+
터미널에서 `uninstall`을 실행하면 무엇을 지울지(도구 하나, 고른 항목, 전부) 고를 수 있고, `--dry-run`을 붙이면 지우기 전에 계획을 먼저 보여 준다. 전부 지울 때는 하네스가 쓴 파일만 하나씩 지운다. `.claude/`, `.codex/`, `.opencode/` 안에 내가 넣어 둔 파일은 제자리에 그대로 남고, 하네스가 대신 자리를 차지했던 내 파일은 원래 자리로 되돌려 놓는다.
|
|
202
202
|
|
|
203
203
|
**이미 진행 중인 프로젝트에 설치해도 된다.** 내가 고친 파일을 바꿔야 할 때는 같은 폴더에 시간이 적힌 백업을 먼저 만들고 그 경로를 알려 준다. 내가 쓰거나 고친 파일은 백업 없이 지우지 않고, 기존 `.mcp.json`의 서버도 덮어쓰지 않고 합친다([기존 프로젝트에 설치하기](docs/USAGE.md#installing-into-an-existing-project)).
|
|
204
204
|
|
package/README.md
CHANGED
|
@@ -166,7 +166,7 @@ A track is a starting setup for a dev stack or a kind of work: the top nine rows
|
|
|
166
166
|
| `project-management` | PM work | None |
|
|
167
167
|
| `growth-marketing` | Growth and content marketing | None (`marketingskills` available) |
|
|
168
168
|
|
|
169
|
-
MCP servers come too. Every track gets `context7` (current library docs). Web tracks (`csr-*`, `ssr-*`, `full`) add `chrome-devtools`, with Google's usage statistics turned off. The `csr-*` and `ssr-htmx` tracks add `railway-mcp-server` (Railway's remote server — you sign in on first use), and `csr-supabase` adds `supabase
|
|
169
|
+
MCP servers come too. Every track gets `context7` (current library docs). Web tracks (`csr-*`, `ssr-*`, `full`) add `chrome-devtools`, with Google's usage statistics turned off. The `csr-*` and `ssr-htmx` tracks add `railway-mcp-server` (Railway's remote server — you sign in on first use), and `csr-supabase` adds `supabase` (Supabase's remote server — you sign in on first use). `full` gets both. On `ssr-nextjs`, Railway MCP is not a default; pick it if you want it. Vercel's and GitHub's official remote servers (`vercel`, `github-mcp`) are never pre-checked — add them with `--with`. Each server is a row in step 3 of the wizard: uncheck it or pass `--without <name>` (e.g. `--without context7`) to leave it out of `.mcp.json`, Codex and OpenCode.
|
|
170
170
|
|
|
171
171
|
More external assets are never pre-checked but can be added at step 3 or with `--with <id>`:
|
|
172
172
|
|
|
@@ -191,7 +191,7 @@ Each track's full set is in [docs/TRACKS.md](docs/TRACKS.md). Every asset's sour
|
|
|
191
191
|
|
|
192
192
|
`update` refreshes what the harness installed, adds what a newer release introduced, and puts back harness files that went missing — a hook script, a server in `.mcp.json`, a section of `AGENTS.md`. What you dropped on purpose with `--without` stays out. It never installs a tool you did not choose. `update --only skills` limits it to one group.
|
|
193
193
|
|
|
194
|
-
In a terminal, `uninstall` offers three choices (one tool, selected assets, or everything), and `--dry-run` shows the plan first. When you remove everything,
|
|
194
|
+
In a terminal, `uninstall` offers three choices (one tool, selected assets, or everything), and `--dry-run` shows the plan first. When you remove everything, only the files the harness wrote are removed, one by one; your own files in `.claude/`, `.codex/` and `.opencode/` stay where they are, and a file of yours the harness had replaced is put back.
|
|
195
195
|
|
|
196
196
|
**Safe on an existing project.** Before replacing a file you edited, the harness writes a timestamped backup next to it and prints the path. Nothing you wrote or edited is deleted without a backup beside it, and your existing `.mcp.json` servers are merged, not replaced ([installing into an existing project](docs/USAGE.md#installing-into-an-existing-project)).
|
|
197
197
|
|
|
@@ -280,6 +280,53 @@ var EXTERNAL_ASSETS = [
|
|
|
280
280
|
condition: { kind: "has-dev-track" },
|
|
281
281
|
method: { kind: "internal", key: "external-model-consult" }
|
|
282
282
|
},
|
|
283
|
+
{
|
|
284
|
+
// #729 (ADR-109) — 토론 정책(참여자 · 독립성 · 라운드 · 예산 · 재시도 · 대체 · 복귀 · 통합)은 이 스킬만
|
|
285
|
+
// 소유한다. 하위 경로(external-model-consult · 브라우저 위임 3종)는 실행 매개변수와 결과·상태만 맡는다.
|
|
286
|
+
// has-dev-track 인 이유: 브라우저 전제가 없다 — external-model-consult 의 CLI 둘만으로 "서로 다른 실제 모델 2개"가
|
|
287
|
+
// 성립하고, 없는 경로는 실행 시점에 unavailable 로 기록한다. DEV_METHOD 에 넣지 않는다(수단 — ADR-105 D2).
|
|
288
|
+
id: "multi-model-debate",
|
|
289
|
+
tier: "official",
|
|
290
|
+
// uzys 자사 스킬
|
|
291
|
+
description: "Multi-model debate \u2014 two or three different real models answer independently, then only decision-relevant disagreements are cross-examined and checked; uses whichever installed routes are available (external-model-consult CLIs or the browser delegates)",
|
|
292
|
+
category: "dev-tools",
|
|
293
|
+
source: "uzys",
|
|
294
|
+
condition: { kind: "has-dev-track" },
|
|
295
|
+
method: { kind: "internal", key: "multi-model-debate" }
|
|
296
|
+
},
|
|
297
|
+
// #729 (ADR-109, 사용자 결정 2026-10-12) — 브라우저 위임 3종은 opt-in. 실행 전제(브라우저 도구 · 로그인된 브라우저 ·
|
|
298
|
+
// 그 서비스 계정)가 하네스 밖에 있고 Codex CLI 에는 브라우저가 없다(공식 문서). #489 가 agent-browser 를 opt-in 으로
|
|
299
|
+
// 내린 축과 같다. 설치는 디렉터리 복사뿐이다 — `--with <id>` · 위저드 체크로 켠다.
|
|
300
|
+
{
|
|
301
|
+
id: "gemini-delegate",
|
|
302
|
+
tier: "official",
|
|
303
|
+
// uzys 자사 스킬
|
|
304
|
+
description: "Gemini delegate \u2014 hand design, review, or Korean polishing to Gemini on the web and collect the answer (needs a browser tool + your logged-in browser)",
|
|
305
|
+
category: "dev-tools",
|
|
306
|
+
source: "uzys",
|
|
307
|
+
condition: { kind: "opt-in" },
|
|
308
|
+
method: { kind: "internal", key: "gemini-delegate" }
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
id: "chatgpt-delegate",
|
|
312
|
+
tier: "official",
|
|
313
|
+
// uzys 자사 스킬
|
|
314
|
+
description: "ChatGPT delegate \u2014 hand design, planning, or review to ChatGPT on the web and collect the answer (needs a browser tool + your logged-in browser)",
|
|
315
|
+
category: "dev-tools",
|
|
316
|
+
source: "uzys",
|
|
317
|
+
condition: { kind: "opt-in" },
|
|
318
|
+
method: { kind: "internal", key: "chatgpt-delegate" }
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
id: "genspark-delegate",
|
|
322
|
+
tier: "official",
|
|
323
|
+
// uzys 자사 스킬
|
|
324
|
+
description: "Genspark delegate \u2014 hand design or planning to Genspark AI Chat, or generate and download images with AI Image (needs a browser tool + your logged-in browser)",
|
|
325
|
+
category: "dev-tools",
|
|
326
|
+
source: "uzys",
|
|
327
|
+
condition: { kind: "opt-in" },
|
|
328
|
+
method: { kind: "internal", key: "genspark-delegate" }
|
|
329
|
+
},
|
|
283
330
|
{
|
|
284
331
|
// 복원 9종이 아니라 신설이다 — 이관 이력이 없다.
|
|
285
332
|
// 전 트랙인 이유: 위임과 요청 정규화는 개발 트랙의 행위가 아니라 **전 트랙의 행위**다.
|
|
@@ -458,6 +505,32 @@ var EXTERNAL_ASSETS = [
|
|
|
458
505
|
cliSupportOverride: ["claude", "codex", "opencode"],
|
|
459
506
|
method: { kind: "internal", key: "chrome-devtools" }
|
|
460
507
|
},
|
|
508
|
+
// #751 — Context7 MCP. 트랙 표 행의 패턴 `*` 가 모든 트랙의 기본이라 위저드 3단계에 늘 체크된 채 보이고, 풀거나
|
|
509
|
+
// `--without context7` 이면 `.mcp.json` · Codex · OpenCode 세 자리에서 빠진다(#709 · #722 와 같은 경로). 기본값은 그대로다.
|
|
510
|
+
{
|
|
511
|
+
id: "context7",
|
|
512
|
+
tier: "vetted",
|
|
513
|
+
// upstash/context7 62.9k (REPO_OVERRIDE)
|
|
514
|
+
description: "Context7 MCP \u2014 current, version-specific library docs for the agent, in .mcp.json, Codex and OpenCode. Default on every track; uncheck it to leave it out",
|
|
515
|
+
category: "understanding",
|
|
516
|
+
source: "upstash",
|
|
517
|
+
condition: { kind: "opt-in" },
|
|
518
|
+
cliSupportOverride: ["claude", "codex", "opencode"],
|
|
519
|
+
method: { kind: "internal", key: "context7" }
|
|
520
|
+
},
|
|
521
|
+
// #751 — Supabase MCP. 트랙 표 행이 csr-supabase · full 의 기본이고, 이 항목은 그 밖의 트랙에서 고르게 · 기본 트랙에서
|
|
522
|
+
// 빼게 한다. 서버 정의(명령 · 인자)는 트랙 표 한 곳이다.
|
|
523
|
+
{
|
|
524
|
+
id: "supabase",
|
|
525
|
+
tier: "vetted",
|
|
526
|
+
// supabase/mcp 2.9k (REPO_OVERRIDE)
|
|
527
|
+
description: "Supabase's official remote MCP (https://mcp.supabase.com/mcp, signs in with OAuth on first use) in .mcp.json, Codex and OpenCode. Default on csr-supabase \xB7 full; check it to add it on any other track. Only if this project uses Supabase",
|
|
528
|
+
category: "backend",
|
|
529
|
+
source: "supabase",
|
|
530
|
+
condition: { kind: "opt-in" },
|
|
531
|
+
cliSupportOverride: ["claude", "codex", "opencode"],
|
|
532
|
+
method: { kind: "internal", key: "supabase" }
|
|
533
|
+
},
|
|
461
534
|
// === csr-supabase|full CLI ===
|
|
462
535
|
{
|
|
463
536
|
id: "vercel-cli",
|
|
@@ -603,7 +676,7 @@ var EXTERNAL_ASSETS = [
|
|
|
603
676
|
pluginId: "security-guidance@claude-plugins-official"
|
|
604
677
|
}
|
|
605
678
|
},
|
|
606
|
-
// v26.110.0 (ADR-039) — context7 플러그인은 **미등록** (검토 후 철회): templates/mcp.json ·
|
|
679
|
+
// v26.110.0 (ADR-039) — context7 플러그인은 **미등록** (검토 후 철회): 트랙 표(#751 전 templates/mcp.json) ·
|
|
607
680
|
// codex config.toml.template · opencode 설정이 이미 @upstash/context7-mcp 를 기본 wiring —
|
|
608
681
|
// 플러그인 추가 = 동일 서버 중복 등록이고 도달 범위도 더 좁다(plugin=claude-only vs
|
|
609
682
|
// 템플릿=claude+codex+opencode). "문서 조회 기본 제공" 요구는 기충족.
|
|
@@ -935,7 +1008,12 @@ var INTERNAL_BUNDLED_SKILL_IDS = [
|
|
|
935
1008
|
"model-orchestration",
|
|
936
1009
|
"external-model-consult",
|
|
937
1010
|
"self-hosted-github-runner",
|
|
938
|
-
"natural-korean"
|
|
1011
|
+
"natural-korean",
|
|
1012
|
+
// #729 (ADR-109) — 토론(개발 트랙 기본) + 브라우저 위임 3종(opt-in). condition 이 설치를 가른다.
|
|
1013
|
+
"multi-model-debate",
|
|
1014
|
+
"gemini-delegate",
|
|
1015
|
+
"chatgpt-delegate",
|
|
1016
|
+
"genspark-delegate"
|
|
939
1017
|
];
|
|
940
1018
|
var CONTINUOUS_SKILLS = [
|
|
941
1019
|
{
|
|
@@ -1038,14 +1116,14 @@ init_esm_shims();
|
|
|
1038
1116
|
|
|
1039
1117
|
// src/install-log.ts
|
|
1040
1118
|
init_esm_shims();
|
|
1041
|
-
import { createHash
|
|
1042
|
-
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync
|
|
1119
|
+
import { createHash } from "crypto";
|
|
1120
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync, statSync, writeFileSync as writeFileSync2 } from "fs";
|
|
1043
1121
|
import { dirname as dirname3, join as join4 } from "path";
|
|
1044
1122
|
|
|
1045
1123
|
// package.json
|
|
1046
1124
|
var package_default = {
|
|
1047
1125
|
name: "@uzysjung/agent-harness",
|
|
1048
|
-
version: "26.
|
|
1126
|
+
version: "26.169.0",
|
|
1049
1127
|
description: "Curate vetted AI-coding skills & plugins by your tech stack \u2014 install only what you need, across Claude Code, Codex, OpenCode & Antigravity",
|
|
1050
1128
|
type: "module",
|
|
1051
1129
|
publishConfig: {
|
|
@@ -1183,7 +1261,6 @@ function targetsInclude(targets, base) {
|
|
|
1183
1261
|
|
|
1184
1262
|
// src/fs-ops.ts
|
|
1185
1263
|
init_esm_shims();
|
|
1186
|
-
import { createHash } from "crypto";
|
|
1187
1264
|
import {
|
|
1188
1265
|
copyFileSync,
|
|
1189
1266
|
existsSync,
|
|
@@ -1191,12 +1268,7 @@ import {
|
|
|
1191
1268
|
mkdirSync,
|
|
1192
1269
|
readdirSync,
|
|
1193
1270
|
readFileSync,
|
|
1194
|
-
|
|
1195
|
-
realpathSync as realpathSync2,
|
|
1196
|
-
renameSync,
|
|
1197
|
-
rmdirSync,
|
|
1198
|
-
rmSync,
|
|
1199
|
-
symlinkSync
|
|
1271
|
+
writeFileSync
|
|
1200
1272
|
} from "fs";
|
|
1201
1273
|
import { dirname as dirname2, join as join2 } from "path";
|
|
1202
1274
|
|
|
@@ -1325,48 +1397,19 @@ function claimBackupPath(base, claim) {
|
|
|
1325
1397
|
}
|
|
1326
1398
|
throw new Error(`Cannot allocate a backup path for ${base} (${MAX_BACKUP_CLAIMS} taken)`);
|
|
1327
1399
|
}
|
|
1328
|
-
function backupDir(target, now = /* @__PURE__ */ new Date()) {
|
|
1329
|
-
if (!existsSync(target)) {
|
|
1330
|
-
return null;
|
|
1331
|
-
}
|
|
1332
|
-
const backup = claimBackupPath(`${target}.backup-${formatStamp(now)}`, (c) => mkdirSync(c));
|
|
1333
|
-
rmdirSync(backup);
|
|
1334
|
-
renameSync(target, backup);
|
|
1335
|
-
return backup;
|
|
1336
|
-
}
|
|
1337
|
-
function copyBackupDir(target, now = /* @__PURE__ */ new Date()) {
|
|
1338
|
-
if (!existsSync(target)) {
|
|
1339
|
-
return null;
|
|
1340
|
-
}
|
|
1341
|
-
const backup = claimBackupPath(`${target}.backup-${formatStamp(now)}`, (c) => mkdirSync(c));
|
|
1342
|
-
try {
|
|
1343
|
-
copyTreePreservingLinks(realpathSync2(target), backup);
|
|
1344
|
-
} catch (e) {
|
|
1345
|
-
rmSync(backup, { recursive: true, force: true });
|
|
1346
|
-
const detail = e instanceof Error ? e.message : String(e);
|
|
1347
|
-
throw new Error(`backup of ${target} failed, partial copy removed \u2014 ${detail}`);
|
|
1348
|
-
}
|
|
1349
|
-
return backup;
|
|
1350
|
-
}
|
|
1351
|
-
function copyTreePreservingLinks(source, target) {
|
|
1352
|
-
mkdirSync(target, { recursive: true });
|
|
1353
|
-
for (const entry of readdirSync(source, { withFileTypes: true })) {
|
|
1354
|
-
const src = join2(source, entry.name);
|
|
1355
|
-
const dst = join2(target, entry.name);
|
|
1356
|
-
if (entry.isSymbolicLink()) {
|
|
1357
|
-
symlinkSync(readlinkSync2(src), dst);
|
|
1358
|
-
continue;
|
|
1359
|
-
}
|
|
1360
|
-
if (entry.isDirectory()) copyTreePreservingLinks(src, dst);
|
|
1361
|
-
else if (entry.isFile()) copyFile(src, dst);
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
1400
|
function backupFile(target, now = /* @__PURE__ */ new Date()) {
|
|
1365
1401
|
return claimBackupPath(
|
|
1366
1402
|
`${target}.backup-${formatStamp(now)}`,
|
|
1367
1403
|
(c) => copyFileSync(target, c, fsConstants.COPYFILE_EXCL)
|
|
1368
1404
|
);
|
|
1369
1405
|
}
|
|
1406
|
+
function backupContent(target, content, now = /* @__PURE__ */ new Date()) {
|
|
1407
|
+
mkdirSync(dirname2(target), { recursive: true });
|
|
1408
|
+
return claimBackupPath(
|
|
1409
|
+
`${target}.backup-${formatStamp(now)}`,
|
|
1410
|
+
(c) => writeFileSync(c, content, { flag: "wx" })
|
|
1411
|
+
);
|
|
1412
|
+
}
|
|
1370
1413
|
function backupOriginal(backupPath) {
|
|
1371
1414
|
const m = /^(.+)\.backup-\d{8}T\d{6}(?:-\d+)?$/.exec(backupPath);
|
|
1372
1415
|
return m?.[1] ?? null;
|
|
@@ -1387,44 +1430,20 @@ function listFilesRecursive(dir, prefix = "") {
|
|
|
1387
1430
|
function formatStamp(now) {
|
|
1388
1431
|
return now.toISOString().replace(/[-:]/g, "").replace(/\.\d+Z$/, "Z").slice(0, 15);
|
|
1389
1432
|
}
|
|
1433
|
+
var PROJECT_SKELETON_DIRS = [
|
|
1434
|
+
".claude/commands/uzys",
|
|
1435
|
+
".claude/rules",
|
|
1436
|
+
".claude/skills",
|
|
1437
|
+
".claude/agents",
|
|
1438
|
+
".claude/hooks",
|
|
1439
|
+
"docs/decisions"
|
|
1440
|
+
];
|
|
1390
1441
|
function ensureProjectSkeleton(projectDir) {
|
|
1391
|
-
const
|
|
1392
|
-
".claude/commands/uzys",
|
|
1393
|
-
".claude/rules",
|
|
1394
|
-
".claude/skills",
|
|
1395
|
-
".claude/agents",
|
|
1396
|
-
".claude/hooks",
|
|
1397
|
-
"docs/decisions"
|
|
1398
|
-
];
|
|
1399
|
-
for (const d of dirs) {
|
|
1442
|
+
for (const d of PROJECT_SKELETON_DIRS) {
|
|
1400
1443
|
if (outsideProjectTarget(projectDir, join2(projectDir, d)) !== null) continue;
|
|
1401
1444
|
mkdirSync(join2(projectDir, d), { recursive: true });
|
|
1402
1445
|
}
|
|
1403
1446
|
}
|
|
1404
|
-
function dirTreesIdentical(a, b) {
|
|
1405
|
-
if (!existsSync(a) || !existsSync(b)) return false;
|
|
1406
|
-
const signature = (root, rel = "", out = /* @__PURE__ */ new Map()) => {
|
|
1407
|
-
for (const e of readdirSync(join2(root, rel), { withFileTypes: true })) {
|
|
1408
|
-
const r = rel === "" ? e.name : `${rel}/${e.name}`;
|
|
1409
|
-
if (e.isSymbolicLink()) out.set(r, `link:${readlinkSync2(join2(root, r))}`);
|
|
1410
|
-
else if (e.isDirectory()) signature(root, r, out);
|
|
1411
|
-
else if (e.isFile()) {
|
|
1412
|
-
out.set(
|
|
1413
|
-
r,
|
|
1414
|
-
createHash("sha256").update(readFileSync(join2(root, r))).digest("hex")
|
|
1415
|
-
);
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
|
-
return out;
|
|
1419
|
-
};
|
|
1420
|
-
const sa = signature(a);
|
|
1421
|
-
const sb = signature(b);
|
|
1422
|
-
if (sa.size !== sb.size) return false;
|
|
1423
|
-
for (const [rel, sha] of sa) {
|
|
1424
|
-
if (sb.get(rel) !== sha) return false;
|
|
1425
|
-
}
|
|
1426
|
-
return true;
|
|
1427
|
-
}
|
|
1428
1447
|
function backupIfLossyUtf8(target, now = /* @__PURE__ */ new Date()) {
|
|
1429
1448
|
if (!existsSync(target)) return null;
|
|
1430
1449
|
let raw;
|
|
@@ -1641,7 +1660,7 @@ function mergeAssets(previous, current) {
|
|
|
1641
1660
|
];
|
|
1642
1661
|
}
|
|
1643
1662
|
function hashContent(content) {
|
|
1644
|
-
return
|
|
1663
|
+
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
1645
1664
|
}
|
|
1646
1665
|
function isHarnessOwned(baseline, key, current) {
|
|
1647
1666
|
const recorded = baseline.get(key);
|
|
@@ -1679,7 +1698,7 @@ function writeInstallLog(projectDir, log) {
|
|
|
1679
1698
|
const path2 = installLogPath(projectDir);
|
|
1680
1699
|
mkdirSync2(dirname3(path2), { recursive: true });
|
|
1681
1700
|
const marked = { ...normalizeLogOrder(log), excludedKeysMigrated: true };
|
|
1682
|
-
|
|
1701
|
+
writeFileSync2(path2, `${JSON.stringify(marked, null, 2)}
|
|
1683
1702
|
`, "utf8");
|
|
1684
1703
|
migrateAwayLegacyLog(projectDir);
|
|
1685
1704
|
return path2;
|
|
@@ -1701,7 +1720,7 @@ function migrateAwayLegacyLog(projectDir) {
|
|
|
1701
1720
|
const legacy = legacyInstallLogPath(projectDir);
|
|
1702
1721
|
if (!existsSync2(legacy)) return;
|
|
1703
1722
|
try {
|
|
1704
|
-
|
|
1723
|
+
rmSync(legacy);
|
|
1705
1724
|
} catch {
|
|
1706
1725
|
}
|
|
1707
1726
|
}
|
|
@@ -2216,6 +2235,14 @@ var RETIRED_PATHS = [
|
|
|
2216
2235
|
"hooks/task-brief-nudge.sh",
|
|
2217
2236
|
"hooks/uncommitted-check.sh"
|
|
2218
2237
|
];
|
|
2238
|
+
var RETIRED_HOOK_WIRING_REFS = [
|
|
2239
|
+
// 6617766 (2026-04-14, phase4b) 배선 → c8fdef1 (2026-05-03, CL-v2 observer 중복 fire 제거) 제거.
|
|
2240
|
+
// PreToolUse · PostToolUse 각각 matcher "*" 묶음 하나 — `observe.sh pre|post`, async.
|
|
2241
|
+
"skills/continuous-learning-v2/hooks/observe.sh",
|
|
2242
|
+
// 5defc58 (2026-04-14, wire strategic-compact) 배선 → a125453 (2026-09-13, #444 스킬 3종 은퇴) 제거.
|
|
2243
|
+
// PreToolUse 의 protect-files 묶음 안 두 번째 핸들러, async.
|
|
2244
|
+
"skills/strategic-compact/suggest-compact.sh"
|
|
2245
|
+
];
|
|
2219
2246
|
var RETIRED_AGENT_IDS = RETIRED_PATHS.filter(
|
|
2220
2247
|
(p) => p.startsWith("agents/")
|
|
2221
2248
|
).map((p) => p.slice("agents/".length).replace(/\.md$/, ""));
|
|
@@ -2605,13 +2632,12 @@ export {
|
|
|
2605
2632
|
ensureDir,
|
|
2606
2633
|
copyFile,
|
|
2607
2634
|
copyDir,
|
|
2608
|
-
backupDir,
|
|
2609
|
-
copyBackupDir,
|
|
2610
2635
|
backupFile,
|
|
2636
|
+
backupContent,
|
|
2611
2637
|
backupOriginal,
|
|
2612
2638
|
listFilesRecursive,
|
|
2639
|
+
PROJECT_SKELETON_DIRS,
|
|
2613
2640
|
ensureProjectSkeleton,
|
|
2614
|
-
dirTreesIdentical,
|
|
2615
2641
|
backupIfLossyUtf8,
|
|
2616
2642
|
HARNESS_ANCHOR_FILE,
|
|
2617
2643
|
HARNESS_IMPORT_LINE,
|
|
@@ -2630,6 +2656,7 @@ export {
|
|
|
2630
2656
|
TRACK_AGENTS,
|
|
2631
2657
|
RETIRED_AGENTS,
|
|
2632
2658
|
RETIRED_PATHS,
|
|
2659
|
+
RETIRED_HOOK_WIRING_REFS,
|
|
2633
2660
|
RETIRED_AGENT_IDS,
|
|
2634
2661
|
isCliNeutralTarget,
|
|
2635
2662
|
buildManifest,
|
|
@@ -2641,6 +2668,7 @@ export {
|
|
|
2641
2668
|
LEGACY_INSTALL_LOG_DIR,
|
|
2642
2669
|
POLICY_DIRS,
|
|
2643
2670
|
installedClis,
|
|
2671
|
+
buildAssetEntries,
|
|
2644
2672
|
buildInstallLog,
|
|
2645
2673
|
mergeRootFiles,
|
|
2646
2674
|
hashContent,
|
|
@@ -2671,4 +2699,4 @@ export {
|
|
|
2671
2699
|
CATEGORIES,
|
|
2672
2700
|
CATEGORY_TITLES
|
|
2673
2701
|
};
|
|
2674
|
-
//# sourceMappingURL=chunk-
|
|
2702
|
+
//# sourceMappingURL=chunk-SU2RUN2W.js.map
|