@uzysjung/agent-harness 26.148.1 → 26.150.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/dist/{chunk-PTUM2NI3.js → chunk-NKBUDHPC.js} +118 -28
- package/dist/chunk-NKBUDHPC.js.map +1 -0
- package/dist/index.js +150 -126
- package/dist/index.js.map +1 -1
- package/dist/trust-tier-drift.js +5 -1
- package/dist/trust-tier-drift.js.map +1 -1
- package/package.json +1 -1
- package/templates/hooks/session-start.sh +57 -3
- package/templates/rules/ship-checklist.md +4 -3
- package/templates/rules/test-policy.md +12 -3
- package/templates/skills/audit-service-gaps/SKILL.md +6 -7
- package/templates/skills/clear-korean-communication/SKILL.md +8 -13
- package/templates/skills/compaction-handoff/SKILL.md +32 -15
- package/templates/skills/external-model-consult/SKILL.md +13 -24
- package/templates/skills/humanize-korean/SKILL.md +228 -0
- package/templates/skills/model-orchestration/SKILL.md +11 -15
- package/templates/skills/north-star/NORTH_STAR.template.md +106 -47
- package/templates/skills/north-star/SKILL.md +234 -80
- package/templates/skills/north-star/references/roadmap-method.md +62 -12
- package/templates/skills/self-hosted-github-runner/SKILL.md +328 -0
- package/templates/skills/task-brief/SKILL.md +9 -11
- package/templates/skills/verification-loop/SKILL.md +23 -0
- package/dist/chunk-PTUM2NI3.js.map +0 -1
|
@@ -287,6 +287,36 @@ var EXTERNAL_ASSETS = [
|
|
|
287
287
|
condition: { kind: "any-track", tracks: [...TRACKS] },
|
|
288
288
|
method: { kind: "internal", key: "audit-harness-fit" }
|
|
289
289
|
},
|
|
290
|
+
{
|
|
291
|
+
// CI 가 멈췄을 때(결제 실패·쿼터 소진·Actions 장애) 검증을 포기하지도, 위조하지도 않는 절차.
|
|
292
|
+
// has-dev-track 인 이유: 이건 **누가 요청해서 켜는 것이 아니라 사고가 났을 때 켜지는** 것이다.
|
|
293
|
+
// CI 가 죽고 나서야 필요해지는 자산을 opt-in 으로 두면, 정작 그 순간에 없다. 대신 executive
|
|
294
|
+
// 트랙에는 깔지 않는다 — 거기엔 워크플로가 없다.
|
|
295
|
+
// DEV_METHOD_SKILL_IDS 에 넣지 않는 이유: 저건 wizard 의 "하네스 방법론 N종" 묶음이고,
|
|
296
|
+
// 이건 방법론이 아니라 사고 대응 런북이다. 묶음에 끼면 묶음의 뜻이 흐려진다.
|
|
297
|
+
id: "self-hosted-github-runner",
|
|
298
|
+
tier: "official",
|
|
299
|
+
// uzys 자사 스킬
|
|
300
|
+
description: "Self-hosted GitHub runner \u2014 when hosted runners stop (billing failure, spending limit, minutes exhausted, org quota, Actions outage), run the repo's existing workflow files unchanged on a Docker self-hosted runner instead of copying CI steps into a local script; covers runner-label switching, architecture and cache-key traps, container isolation, the risk that pull_request jobs then execute on your own machine, and the rollback path",
|
|
301
|
+
category: "dev-tools",
|
|
302
|
+
source: "uzys",
|
|
303
|
+
condition: { kind: "has-dev-track" },
|
|
304
|
+
method: { kind: "internal", key: "self-hosted-github-runner" }
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
// 트랙과 무관한 글쓰기 규율이라 어느 트랙에서도 고를 수 있고, 어느 트랙에도 자동으로는
|
|
308
|
+
// 안 깔린다(opt-in). 한국어로 쓰지 않는 사용자에게 기본 설치되면 그대로 낭비다.
|
|
309
|
+
// clear-korean-communication 과의 경계: 저쪽은 **무엇을 어떤 형식으로 말할지**(설명·승인
|
|
310
|
+
// 요청의 구조)이고, 이쪽은 **이미 쓴 글의 문체**를 진단해 최소 수정한다.
|
|
311
|
+
id: "humanize-korean",
|
|
312
|
+
tier: "official",
|
|
313
|
+
// uzys 자사 스킬
|
|
314
|
+
description: "Humanize Korean \u2014 diagnose what actually reads as translationese, AI clich\xE9, or mechanical structure in Korean prose, then fix only what the diagnosis justifies, preserving facts, numbers, terminology and register (opt-in). References epoko77-ai/im-not-ai",
|
|
315
|
+
category: "workflow",
|
|
316
|
+
source: "uzys",
|
|
317
|
+
condition: { kind: "opt-in" },
|
|
318
|
+
method: { kind: "internal", key: "humanize-korean" }
|
|
319
|
+
},
|
|
290
320
|
// === Option-gated (v26.42.0 — opt-in, BREAKING vs prior has-dev-track auto-install) ===
|
|
291
321
|
{
|
|
292
322
|
id: "addy-agent-skills",
|
|
@@ -999,7 +1029,9 @@ var INTERNAL_BUNDLED_SKILL_IDS = [
|
|
|
999
1029
|
"task-brief",
|
|
1000
1030
|
"audit-harness-fit",
|
|
1001
1031
|
"model-orchestration",
|
|
1002
|
-
"external-model-consult"
|
|
1032
|
+
"external-model-consult",
|
|
1033
|
+
"self-hosted-github-runner",
|
|
1034
|
+
"humanize-korean"
|
|
1003
1035
|
];
|
|
1004
1036
|
var TRUST_TIER = Object.fromEntries(
|
|
1005
1037
|
EXTERNAL_ASSETS.map((a) => [a.id, a.tier])
|
|
@@ -1440,12 +1472,21 @@ var FILL_SPECS = {
|
|
|
1440
1472
|
placeholder: "the single command that proves a change is safe, and the done bar"
|
|
1441
1473
|
}
|
|
1442
1474
|
};
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1475
|
+
function anchorLine(surface) {
|
|
1476
|
+
if (surface === "claude") {
|
|
1477
|
+
return `> The working principles live in this project's harness anchor \`${HARNESS_ANCHOR_FILE}\`, imported at the bottom of this file. Everything above that import is **project-specific context only**.`;
|
|
1478
|
+
}
|
|
1479
|
+
const self = surface === "antigravity-rule" ? "`.agents/rules/uzys-harness.md`" : "`AGENTS.md`";
|
|
1480
|
+
return `> **This file (${self}) is the harness anchor** \u2014 it carries the working principles in full, further down. Only the \`## \u2026\` sections immediately below are project-specific context for you to fill in.`;
|
|
1481
|
+
}
|
|
1482
|
+
function scaffoldBanner(surface) {
|
|
1483
|
+
return [
|
|
1484
|
+
"> \u2699\uFE0F **SCAFFOLD \u2014 not filled in yet.** The sections below are a fill-in template for THIS project, not verified facts.",
|
|
1485
|
+
"> To fill: open this file and paste each `<!-- FILL: \u2026 -->` comment's instruction into your coding agent (e.g. Claude Code) \u2014 it will inspect the real repo and write the section. You can also fill them by hand; the comments are the instructions.",
|
|
1486
|
+
anchorLine(surface)
|
|
1487
|
+
].join("\n");
|
|
1488
|
+
}
|
|
1489
|
+
function renderFillScaffold(surface = "claude") {
|
|
1449
1490
|
const blocks = FILL_SECTIONS.map((id) => {
|
|
1450
1491
|
const spec = FILL_SPECS[id];
|
|
1451
1492
|
return `## ${spec.title}
|
|
@@ -1454,7 +1495,7 @@ function renderFillScaffold() {
|
|
|
1454
1495
|
|
|
1455
1496
|
_(not filled yet \u2014 ${spec.placeholder})_`;
|
|
1456
1497
|
});
|
|
1457
|
-
return `${
|
|
1498
|
+
return `${scaffoldBanner(surface)}
|
|
1458
1499
|
|
|
1459
1500
|
${blocks.join("\n\n")}`;
|
|
1460
1501
|
}
|
|
@@ -1513,6 +1554,17 @@ function expandTracks(tracks) {
|
|
|
1513
1554
|
}
|
|
1514
1555
|
|
|
1515
1556
|
// src/manifest.ts
|
|
1557
|
+
function buildAssetSpec(ctx) {
|
|
1558
|
+
return {
|
|
1559
|
+
tracks: ctx.tracks,
|
|
1560
|
+
withTauri: isAssetSelected("tauri-desktop", ctx),
|
|
1561
|
+
// v26.55.0 — withEcc gating (ADR-016). withPrune 은 ecc-plugin 사용을 전제한다.
|
|
1562
|
+
withEcc: isAssetSelected("ecc-plugin", ctx) || ctx.options.withPrune === true,
|
|
1563
|
+
// v26.87.0 — internal bundled skills (dev-method + opt-in advisors, v26.95.0). id 별 condition
|
|
1564
|
+
// (has-dev-track vs opt-in)은 isAssetSelected 가 적용한다.
|
|
1565
|
+
selectedInternalSkills: INTERNAL_BUNDLED_SKILL_IDS.filter((id) => isAssetSelected(id, ctx))
|
|
1566
|
+
};
|
|
1567
|
+
}
|
|
1516
1568
|
var all = () => true;
|
|
1517
1569
|
var dev = (s) => hasDevTrack(s.tracks);
|
|
1518
1570
|
var ui = (s) => hasUiTrack(s.tracks);
|
|
@@ -1670,9 +1722,9 @@ function buildManifest(spec) {
|
|
|
1670
1722
|
});
|
|
1671
1723
|
}
|
|
1672
1724
|
m.push({
|
|
1673
|
-
source: "skills/spec-scaling
|
|
1674
|
-
target: ".claude/skills/spec-scaling
|
|
1675
|
-
type: "
|
|
1725
|
+
source: "skills/spec-scaling",
|
|
1726
|
+
target: ".claude/skills/spec-scaling",
|
|
1727
|
+
type: "dir",
|
|
1676
1728
|
applies: all
|
|
1677
1729
|
});
|
|
1678
1730
|
for (const sd of ["market-research", "investor-materials", "investor-outreach"]) {
|
|
@@ -1832,6 +1884,21 @@ function assetCostRows(assetIds, root = resolveBundleRoot()) {
|
|
|
1832
1884
|
bodyTokens: assetBodyTokens(id, root)
|
|
1833
1885
|
})).sort((a, b) => (b.bodyTokens ?? -1) - (a.bodyTokens ?? -1));
|
|
1834
1886
|
}
|
|
1887
|
+
function makeResidentCost(base) {
|
|
1888
|
+
return {
|
|
1889
|
+
...base,
|
|
1890
|
+
perSkillDescriptor: base.perSkillDescriptor ?? {},
|
|
1891
|
+
total: base.rules + base.projectClaudeMd + base.skillDescriptors + base.agentDescriptors,
|
|
1892
|
+
directive: {
|
|
1893
|
+
items: base.items.rules + base.items.claudeMd,
|
|
1894
|
+
tokens: base.rules + base.projectClaudeMd
|
|
1895
|
+
},
|
|
1896
|
+
firing: {
|
|
1897
|
+
items: base.items.skills + base.items.agents,
|
|
1898
|
+
tokens: base.skillDescriptors + base.agentDescriptors
|
|
1899
|
+
}
|
|
1900
|
+
};
|
|
1901
|
+
}
|
|
1835
1902
|
function fileTokens(path2) {
|
|
1836
1903
|
return existsSync3(path2) ? estimateTokens(readFileSync3(path2, "utf8").trim().length) : 0;
|
|
1837
1904
|
}
|
|
@@ -1842,6 +1909,7 @@ function descriptorTokens(path2) {
|
|
|
1842
1909
|
}
|
|
1843
1910
|
function residentCost(entries, root = resolveBundleRoot()) {
|
|
1844
1911
|
const tpl = (source) => join3(root, "templates", source);
|
|
1912
|
+
const perSkill = {};
|
|
1845
1913
|
let rules = 0;
|
|
1846
1914
|
let skillDescriptors = 0;
|
|
1847
1915
|
let agentDescriptors = 0;
|
|
@@ -1856,20 +1924,23 @@ function residentCost(entries, root = resolveBundleRoot()) {
|
|
|
1856
1924
|
agentDescriptors += descriptorTokens(tpl(e.source));
|
|
1857
1925
|
agentItems += 1;
|
|
1858
1926
|
} else if (e.target.startsWith(".claude/skills/")) {
|
|
1859
|
-
|
|
1927
|
+
const t = descriptorTokens(join3(tpl(e.source), "SKILL.md"));
|
|
1928
|
+
skillDescriptors += t;
|
|
1860
1929
|
skillItems += 1;
|
|
1930
|
+
const id = /\.claude\/skills\/([^/]+)/.exec(e.target)?.[1];
|
|
1931
|
+
if (id !== void 0) perSkill[id] = (perSkill[id] ?? 0) + t;
|
|
1861
1932
|
}
|
|
1862
1933
|
}
|
|
1863
1934
|
const harnessAnchor = fileTokens(join3(root, "templates", "CLAUDE.md"));
|
|
1864
1935
|
const projectScaffold = estimateTokens(renderFillScaffold().trim().length);
|
|
1865
1936
|
const projectClaudeMd = harnessAnchor + projectScaffold;
|
|
1866
1937
|
const claudeMdItems = (harnessAnchor > 0 ? 1 : 0) + (projectScaffold > 0 ? 1 : 0);
|
|
1867
|
-
return {
|
|
1938
|
+
return makeResidentCost({
|
|
1868
1939
|
rules,
|
|
1869
1940
|
projectClaudeMd,
|
|
1870
1941
|
skillDescriptors,
|
|
1871
1942
|
agentDescriptors,
|
|
1872
|
-
|
|
1943
|
+
perSkillDescriptor: perSkill,
|
|
1873
1944
|
items: {
|
|
1874
1945
|
rules: ruleItems,
|
|
1875
1946
|
skills: skillItems,
|
|
@@ -1877,7 +1948,7 @@ function residentCost(entries, root = resolveBundleRoot()) {
|
|
|
1877
1948
|
claudeMd: claudeMdItems,
|
|
1878
1949
|
total: ruleItems + skillItems + agentItems + claudeMdItems
|
|
1879
1950
|
}
|
|
1880
|
-
};
|
|
1951
|
+
});
|
|
1881
1952
|
}
|
|
1882
1953
|
function summarizeContextCost(assetIds, root = resolveBundleRoot()) {
|
|
1883
1954
|
let measuredTokens = 0;
|
|
@@ -1896,33 +1967,47 @@ function summarizeContextCost(assetIds, root = resolveBundleRoot()) {
|
|
|
1896
1967
|
function formatResidentCostLine(r, unmeasuredCount) {
|
|
1897
1968
|
if (r.total === 0) return null;
|
|
1898
1969
|
const parts = [
|
|
1899
|
-
`
|
|
1900
|
-
`CLAUDE.md ${r.items.claudeMd} ~${r.projectClaudeMd}`,
|
|
1901
|
-
`
|
|
1902
|
-
`agents ${r.items.agents} ~${r.agentDescriptors}`
|
|
1970
|
+
`directives ${r.directive.items} ~${r.directive.tokens}`,
|
|
1971
|
+
`[rules ${r.items.rules} ~${r.rules} \xB7 CLAUDE.md ${r.items.claudeMd} ~${r.projectClaudeMd}]`,
|
|
1972
|
+
`triggers ${r.firing.items} ~${r.firing.tokens}`,
|
|
1973
|
+
`[skills ${r.items.skills} ~${r.skillDescriptors} \xB7 agents ${r.items.agents} ~${r.agentDescriptors}]`
|
|
1903
1974
|
].join(" \xB7 ");
|
|
1904
1975
|
const external = unmeasuredCount > 0 ? ` \xB7 ${unmeasuredCount} external asset${unmeasuredCount === 1 ? "" : "s"} unmeasured` : "";
|
|
1905
1976
|
return `session-start context cost: ${r.items.total} items resident \xB7 ~${r.total} tokens/session (${parts}${external})`;
|
|
1906
1977
|
}
|
|
1907
1978
|
var RESIDENT_ROWS = [
|
|
1908
|
-
{
|
|
1979
|
+
{
|
|
1980
|
+
// ADR-083 — 축 소계를 **행으로** 낸다. 소계가 없으면 읽는 사람이 네 줄을 머리로 더해야
|
|
1981
|
+
// 하고, 그러면 "무엇을 줄여야 하나"가 표에서 안 보인다.
|
|
1982
|
+
label: "\uC9C0\uC2DC\uBB38",
|
|
1983
|
+
gap: 13,
|
|
1984
|
+
count: (r) => r.directive.items,
|
|
1985
|
+
tokens: (r) => r.directive.tokens
|
|
1986
|
+
},
|
|
1987
|
+
{ label: " rules", gap: 12, count: (r) => r.items.rules, tokens: (r) => r.rules },
|
|
1909
1988
|
{
|
|
1910
1989
|
// 한 행에 두 파일(앵커 + 스캐폴드). 개수 열이 2 를 뱉어 그 사실을 드러낸다 — 라벨로
|
|
1911
1990
|
// 하나만 이름 붙이면 v26.140.0 이전과 같은 거짓 라벨이 된다.
|
|
1912
|
-
label: "CLAUDE.md",
|
|
1913
|
-
gap:
|
|
1991
|
+
label: " CLAUDE.md",
|
|
1992
|
+
gap: 8,
|
|
1914
1993
|
count: (r) => r.items.claudeMd,
|
|
1915
1994
|
tokens: (r) => r.projectClaudeMd
|
|
1916
1995
|
},
|
|
1917
1996
|
{
|
|
1918
|
-
label: "
|
|
1919
|
-
gap:
|
|
1997
|
+
label: "\uBC1C\uD654 \uD45C\uBA74",
|
|
1998
|
+
gap: 10,
|
|
1999
|
+
count: (r) => r.firing.items,
|
|
2000
|
+
tokens: (r) => r.firing.tokens
|
|
2001
|
+
},
|
|
2002
|
+
{
|
|
2003
|
+
label: " skill descriptors",
|
|
2004
|
+
gap: 0,
|
|
1920
2005
|
count: (r) => r.items.skills,
|
|
1921
2006
|
tokens: (r) => r.skillDescriptors
|
|
1922
2007
|
},
|
|
1923
2008
|
{
|
|
1924
|
-
label: "agent descriptors",
|
|
1925
|
-
gap:
|
|
2009
|
+
label: " agent descriptors",
|
|
2010
|
+
gap: 0,
|
|
1926
2011
|
count: (r) => r.items.agents,
|
|
1927
2012
|
tokens: (r) => r.agentDescriptors
|
|
1928
2013
|
}
|
|
@@ -1935,7 +2020,11 @@ function formatResidentCostBlock(r) {
|
|
|
1935
2020
|
(row) => ` ${row.label}${" ".repeat(row.gap)}${n(row.count(r))}\uAC1C ~${row.tokens(r)}`
|
|
1936
2021
|
),
|
|
1937
2022
|
" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
1938
|
-
` \uC0C1\uC8FC \uD569\uACC4 ${n(r.items.total)}\uAC1C \uC0C1\uC8FC \xB7 ~${r.total} tokens/\uC138\uC158
|
|
2023
|
+
` \uC0C1\uC8FC \uD569\uACC4 ${n(r.items.total)}\uAC1C \uC0C1\uC8FC \xB7 ~${r.total} tokens/\uC138\uC158`,
|
|
2024
|
+
"",
|
|
2025
|
+
" \uC9C0\uC2DC\uBB38 = \uC6B0\uB9AC\uAC00 \uD56D\uC0C1 \uC77D\uD788\uAC8C \uB123\uC740 \uAC83. **\uC791\uC744\uC218\uB85D \uC88B\uC740 \uAC12\uC774 \uC544\uB2C8\uB2E4** \u2014 \uD310\uB2E8\uC740",
|
|
2026
|
+
" '\uBD88\uD544\uC694\uD55C \uC9C0\uC2DC\uBB38\uC774 \uC788\uB098'\uB85C \uD55C\uB2E4. ratchet \uC740 \uC870\uC6A9\uD55C \uC99D\uAC00\uB9CC \uB9C9\uB294\uB2E4.",
|
|
2027
|
+
" \uBC1C\uD654 \uD45C\uBA74 = \uC2A4\uD0AC\xB7\uC5D0\uC774\uC804\uD2B8\uAC00 \uBD88\uB9AC\uB824\uACE0 \uC0C1\uC8FC\uC2DC\uD0A4\uB294 descriptor. \uAE4E\uC73C\uBA74 \uC548 \uBD88\uB9B0\uB2E4."
|
|
1939
2028
|
];
|
|
1940
2029
|
}
|
|
1941
2030
|
|
|
@@ -1988,6 +2077,7 @@ export {
|
|
|
1988
2077
|
renderFillScaffold,
|
|
1989
2078
|
upsertHarnessImport,
|
|
1990
2079
|
stripHarnessImport,
|
|
2080
|
+
buildAssetSpec,
|
|
1991
2081
|
resolveRules,
|
|
1992
2082
|
ALL_RULES,
|
|
1993
2083
|
isCliNeutralTarget,
|
|
@@ -2002,4 +2092,4 @@ export {
|
|
|
2002
2092
|
formatResidentCostLine,
|
|
2003
2093
|
formatResidentCostBlock
|
|
2004
2094
|
};
|
|
2005
|
-
//# sourceMappingURL=chunk-
|
|
2095
|
+
//# sourceMappingURL=chunk-NKBUDHPC.js.map
|