@uzysjung/agent-harness 26.115.0 → 26.117.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/index.js CHANGED
@@ -14,17 +14,20 @@ import {
14
14
  assetCliSupport,
15
15
  assetReachesCli,
16
16
  assetTrustTier,
17
+ buildManifest,
17
18
  experimentalOptInCandidates,
18
19
  filterApplicableAssets,
19
- hasDevTrack,
20
+ formatResidentCostLine,
20
21
  hasUiTrack,
21
22
  init_esm_shims,
22
23
  isAssetSelected,
23
24
  isCliBase,
24
25
  isInstallScope,
25
26
  isTrack,
26
- resolveScope
27
- } from "./chunk-P6YR3FBR.js";
27
+ residentCost,
28
+ resolveScope,
29
+ summarizeContextCost
30
+ } from "./chunk-2VII24JD.js";
28
31
 
29
32
  // node_modules/sisteransi/src/index.js
30
33
  var require_src = __commonJS({
@@ -709,7 +712,7 @@ var cac = (name = "") => new CAC(name);
709
712
  // package.json
710
713
  var package_default = {
711
714
  name: "@uzysjung/agent-harness",
712
- version: "26.115.0",
715
+ version: "26.117.0",
713
716
  description: "Curate vetted AI-coding skills & plugins by your tech stack \u2014 install only what you need, across Claude Code, Codex, OpenCode & Antigravity",
714
717
  type: "module",
715
718
  publishConfig: {
@@ -740,7 +743,8 @@ var package_default = {
740
743
  "lint:fix": "biome check --write src tests",
741
744
  format: "biome format --write src tests",
742
745
  ci: "npm run typecheck && npm run lint && npm run test:coverage && npm run build",
743
- prepare: "[ -d dist ] || npm run build"
746
+ prepare: "[ -d dist ] || npm run build",
747
+ "cost:report": "npm run build && node scripts/context-cost-report.mjs"
744
748
  },
745
749
  dependencies: {
746
750
  "@clack/prompts": "^1.3.0",
@@ -763,8 +767,8 @@ var package_default = {
763
767
 
764
768
  // src/commands/install.ts
765
769
  init_esm_shims();
766
- import { resolve as resolve3 } from "path";
767
- import { fileURLToPath as fileURLToPath2 } from "url";
770
+ import { resolve as resolve2 } from "path";
771
+ import { fileURLToPath } from "url";
768
772
 
769
773
  // src/cli-targets.ts
770
774
  init_esm_shims();
@@ -1795,258 +1799,6 @@ function installLogPath(projectDir) {
1795
1799
  return join8(projectDir, ".claude", INSTALL_LOG_FILENAME);
1796
1800
  }
1797
1801
 
1798
- // src/manifest.ts
1799
- init_esm_shims();
1800
- var all = () => true;
1801
- var dev = (s) => hasDevTrack(s.tracks);
1802
- var ui = (s) => hasUiTrack(s.tracks);
1803
- var onTracks = (pattern) => (s) => anyTrack(s.tracks, pattern);
1804
- var COMMON_RULES = ["git-policy", "change-management", "gates-taxonomy", "doc-governance"];
1805
- var DEV_RULES = ["test-policy", "ship-checklist", "code-style", "error-handling"];
1806
- var UI_RULES = ["design-workflow", "playwright-launch", "benchmark-parity"];
1807
- var TRACK_RULES = {
1808
- "csr-supabase": ["shadcn", "api-contract"],
1809
- "csr-fastify": ["shadcn", "api-contract", "database"],
1810
- "csr-fastapi": ["shadcn", "api-contract", "database"],
1811
- "ssr-htmx": ["htmx"],
1812
- "ssr-nextjs": ["nextjs", "shadcn"],
1813
- data: ["pyside6", "data-analysis"],
1814
- executive: [],
1815
- tooling: ["cli-development"],
1816
- full: [
1817
- "shadcn",
1818
- "api-contract",
1819
- "database",
1820
- "htmx",
1821
- "nextjs",
1822
- "pyside6",
1823
- "data-analysis",
1824
- "cli-development"
1825
- ],
1826
- // v0.5.0 — executive-style baselines (no dev rules; common rules only).
1827
- "project-management": [],
1828
- "growth-marketing": []
1829
- };
1830
- function resolveRules(spec) {
1831
- const set = new Set(COMMON_RULES);
1832
- if (hasDevTrack(spec.tracks)) {
1833
- for (const r of DEV_RULES) {
1834
- set.add(r);
1835
- }
1836
- }
1837
- if (spec.withTauri && anyTrack(spec.tracks, "csr-*|full")) {
1838
- set.add("tauri");
1839
- }
1840
- if (hasUiTrack(spec.tracks)) {
1841
- for (const r of UI_RULES) {
1842
- set.add(r);
1843
- }
1844
- }
1845
- for (const t of spec.tracks) {
1846
- for (const r of TRACK_RULES[t]) {
1847
- set.add(r);
1848
- }
1849
- }
1850
- return [...set].sort();
1851
- }
1852
- var CORE_AGENTS = ["reviewer", "data-analyst", "strategist"];
1853
- var CORE_AGENTS_ECC = ["code-reviewer", "security-reviewer"];
1854
- var DEV_AGENTS = ["plan-checker"];
1855
- var DEV_AGENTS_ECC = ["silent-failure-hunter", "build-error-resolver"];
1856
- var ALWAYS_HOOKS = [
1857
- "session-start.sh",
1858
- "protect-files.sh",
1859
- "mcp-pre-exec.sh",
1860
- "spec-drift-check.sh",
1861
- "checkpoint-snapshot.sh"
1862
- ];
1863
- var COMMON_SKILL_DIRS = ["north-star", "gh-issue-workflow"];
1864
- var COMMON_SKILL_DIRS_ECC = ["strategic-compact"];
1865
- var MODIFIED_COMMON_SKILL_DIRS = ["continuous-learning-v2", "deep-research"];
1866
- var DEV_SKILL_DIRS = [];
1867
- var DEV_SKILL_DIRS_ECC = ["agent-introspection-debugging"];
1868
- var MODIFIED_DEV_SKILL_DIRS = ["verification-loop", "eval-harness"];
1869
- var MODIFIED_ECC_SKILL_DIRS = [...MODIFIED_COMMON_SKILL_DIRS, ...MODIFIED_DEV_SKILL_DIRS];
1870
- var UI_SKILL_DIRS = ["ui-visual-review"];
1871
- var UI_SKILL_DIRS_ECC = ["e2e-testing"];
1872
- var PYTHON_SKILL_DIRS_ECC = ["python-patterns", "python-testing"];
1873
- function buildManifest(spec) {
1874
- const m = [];
1875
- for (const r of resolveRules(spec)) {
1876
- m.push({
1877
- source: `rules/${r}.md`,
1878
- target: `.claude/rules/${r}.md`,
1879
- type: "file",
1880
- applies: all
1881
- });
1882
- }
1883
- m.push({
1884
- source: "commands/ecc",
1885
- target: ".claude/commands/ecc",
1886
- type: "dir",
1887
- applies: (s) => !s.withEcc
1888
- });
1889
- m.push({
1890
- source: "CLAUDE.md",
1891
- target: ".claude/CLAUDE.md",
1892
- type: "file",
1893
- applies: all
1894
- });
1895
- for (const a of CORE_AGENTS) {
1896
- m.push({
1897
- source: `agents/${a}.md`,
1898
- target: `.claude/agents/${a}.md`,
1899
- type: "file",
1900
- applies: all
1901
- });
1902
- }
1903
- for (const a of DEV_AGENTS) {
1904
- m.push({
1905
- source: `agents/${a}.md`,
1906
- target: `.claude/agents/${a}.md`,
1907
- type: "file",
1908
- applies: dev
1909
- });
1910
- }
1911
- for (const a of CORE_AGENTS_ECC) {
1912
- m.push({
1913
- source: `agents/${a}.md`,
1914
- target: `.claude/agents/${a}.md`,
1915
- type: "file",
1916
- applies: (s) => !s.withEcc
1917
- });
1918
- }
1919
- for (const a of DEV_AGENTS_ECC) {
1920
- m.push({
1921
- source: `agents/${a}.md`,
1922
- target: `.claude/agents/${a}.md`,
1923
- type: "file",
1924
- applies: (s) => !s.withEcc && hasDevTrack(s.tracks)
1925
- });
1926
- }
1927
- for (const sd of COMMON_SKILL_DIRS) {
1928
- m.push({
1929
- source: `skills/${sd}`,
1930
- target: `.claude/skills/${sd}`,
1931
- type: "dir",
1932
- applies: all
1933
- });
1934
- }
1935
- for (const sd of COMMON_SKILL_DIRS_ECC) {
1936
- m.push({
1937
- source: `skills/${sd}`,
1938
- target: `.claude/skills/${sd}`,
1939
- type: "dir",
1940
- applies: (s) => !s.withEcc
1941
- });
1942
- }
1943
- for (const sd of MODIFIED_COMMON_SKILL_DIRS) {
1944
- m.push({
1945
- source: `skills/${sd}`,
1946
- target: `.claude/skills/${sd}`,
1947
- type: "dir",
1948
- applies: all
1949
- });
1950
- }
1951
- m.push({
1952
- source: "skills/spec-scaling/SKILL.md",
1953
- target: ".claude/skills/spec-scaling/SKILL.md",
1954
- type: "file",
1955
- applies: all
1956
- });
1957
- m.push({
1958
- source: "skills/market-research",
1959
- target: ".claude/skills/market-research",
1960
- type: "dir",
1961
- applies: onTracks("executive|full")
1962
- });
1963
- for (const sd of ["investor-materials", "investor-outreach"]) {
1964
- m.push({
1965
- source: `skills/${sd}`,
1966
- target: `.claude/skills/${sd}`,
1967
- type: "dir",
1968
- applies: onTracks("executive|full")
1969
- });
1970
- }
1971
- m.push({
1972
- source: "skills/nextjs-turbopack",
1973
- target: ".claude/skills/nextjs-turbopack",
1974
- type: "dir",
1975
- applies: onTracks("ssr-nextjs|full")
1976
- });
1977
- for (const sd of INTERNAL_BUNDLED_SKILL_IDS) {
1978
- m.push({
1979
- source: `skills/${sd}`,
1980
- target: `.claude/skills/${sd}`,
1981
- type: "dir",
1982
- applies: (s) => (s.selectedInternalSkills ?? []).includes(sd)
1983
- });
1984
- }
1985
- for (const sd of PYTHON_SKILL_DIRS_ECC) {
1986
- m.push({
1987
- source: `skills/${sd}`,
1988
- target: `.claude/skills/${sd}`,
1989
- type: "dir",
1990
- applies: (s) => !s.withEcc && anyTrack(s.tracks, "data|csr-fastapi|full")
1991
- });
1992
- }
1993
- for (const sd of DEV_SKILL_DIRS) {
1994
- m.push({
1995
- source: `skills/${sd}`,
1996
- target: `.claude/skills/${sd}`,
1997
- type: "dir",
1998
- applies: dev
1999
- });
2000
- }
2001
- for (const sd of DEV_SKILL_DIRS_ECC) {
2002
- m.push({
2003
- source: `skills/${sd}`,
2004
- target: `.claude/skills/${sd}`,
2005
- type: "dir",
2006
- applies: (s) => !s.withEcc && hasDevTrack(s.tracks)
2007
- });
2008
- }
2009
- for (const sd of MODIFIED_DEV_SKILL_DIRS) {
2010
- m.push({
2011
- source: `skills/${sd}`,
2012
- target: `.claude/skills/${sd}`,
2013
- type: "dir",
2014
- applies: dev
2015
- });
2016
- }
2017
- for (const sd of UI_SKILL_DIRS) {
2018
- m.push({
2019
- source: `skills/${sd}`,
2020
- target: `.claude/skills/${sd}`,
2021
- type: "dir",
2022
- applies: ui
2023
- });
2024
- }
2025
- for (const sd of UI_SKILL_DIRS_ECC) {
2026
- m.push({
2027
- source: `skills/${sd}`,
2028
- target: `.claude/skills/${sd}`,
2029
- type: "dir",
2030
- applies: (s) => !s.withEcc && hasUiTrack(s.tracks)
2031
- });
2032
- }
2033
- for (const h2 of ALWAYS_HOOKS) {
2034
- m.push({
2035
- source: `hooks/${h2}`,
2036
- target: `.claude/hooks/${h2}`,
2037
- type: "file",
2038
- applies: all
2039
- });
2040
- }
2041
- m.push({
2042
- source: "settings.json",
2043
- target: ".claude/settings.json",
2044
- type: "file",
2045
- applies: all
2046
- });
2047
- return m;
2048
- }
2049
-
2050
1802
  // src/mcp-merge.ts
2051
1803
  init_esm_shims();
2052
1804
  import { existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
@@ -2774,54 +2526,6 @@ function listHookFiles(hookDir) {
2774
2526
  // src/commands/install-render.ts
2775
2527
  init_esm_shims();
2776
2528
 
2777
- // src/context-cost.ts
2778
- init_esm_shims();
2779
- import { existsSync as existsSync13, readFileSync as readFileSync12 } from "fs";
2780
- import { join as join12, resolve as resolve2 } from "path";
2781
- import { fileURLToPath } from "url";
2782
- var CHARS_PER_TOKEN = 4;
2783
- function estimateTokens(chars) {
2784
- return Math.ceil(chars / CHARS_PER_TOKEN);
2785
- }
2786
- function resolveBundleRoot() {
2787
- return resolve2(fileURLToPath(new URL(".", import.meta.url)), "..");
2788
- }
2789
- function extractFrontmatter(content) {
2790
- const m = content.match(/^?---\r?\n([\s\S]*?)\r?\n---/);
2791
- return m?.[1] ?? null;
2792
- }
2793
- function assetDescriptorTokens(assetId, root = resolveBundleRoot()) {
2794
- const asset = EXTERNAL_ASSETS.find((a) => a.id === assetId);
2795
- if (!asset || asset.method.kind !== "internal") return null;
2796
- const skillMd = join12(root, "templates", "skills", asset.method.key, "SKILL.md");
2797
- if (!existsSync13(skillMd)) return null;
2798
- const fm = extractFrontmatter(readFileSync12(skillMd, "utf8"));
2799
- return fm === null ? null : estimateTokens(fm.length);
2800
- }
2801
- function summarizeContextCost(assetIds, root = resolveBundleRoot()) {
2802
- let measuredTokens = 0;
2803
- let measuredCount = 0;
2804
- let unmeasuredCount = 0;
2805
- for (const id of assetIds) {
2806
- const tokens = assetDescriptorTokens(id, root);
2807
- if (tokens === null) unmeasuredCount += 1;
2808
- else {
2809
- measuredTokens += tokens;
2810
- measuredCount += 1;
2811
- }
2812
- }
2813
- return { measuredTokens, measuredCount, unmeasuredCount };
2814
- }
2815
- function formatContextCostLine(s) {
2816
- if (s.measuredCount === 0 && s.unmeasuredCount === 0) return null;
2817
- if (s.measuredCount === 0) {
2818
- return `session-start context cost: unmeasured (${s.unmeasuredCount} external asset${s.unmeasuredCount === 1 ? "" : "s"})`;
2819
- }
2820
- const skills = `${s.measuredCount} bundled skill${s.measuredCount === 1 ? "" : "s"} measured`;
2821
- const external = s.unmeasuredCount > 0 ? ` \xB7 ${s.unmeasuredCount} external unmeasured` : "";
2822
- return `session-start context cost: ~${s.measuredTokens} tokens (${skills}${external})`;
2823
- }
2824
-
2825
2529
  // src/preset-recommend.ts
2826
2530
  init_esm_shims();
2827
2531
  function recommendedExternalAssets(presets) {
@@ -2886,7 +2590,10 @@ function renderInstallHeader(log, spec, mode) {
2886
2590
  for (const [cat, ids] of groupAssetsByCategory(finalAssets)) {
2887
2591
  log(` ${c.dim(`\xB7 ${cat}:`)} ${ids.join(", ")}`);
2888
2592
  }
2889
- const cost = formatContextCostLine(summarizeContextCost(finalAssets));
2593
+ const cost = formatResidentCostLine(
2594
+ residentCost(buildManifest(spec).filter((e2) => e2.applies(spec))),
2595
+ summarizeContextCost(finalAssets).unmeasuredCount
2596
+ );
2890
2597
  if (cost) log(` ${c.dim(`\xB7 ${cost}`)}`);
2891
2598
  }
2892
2599
  log("");
@@ -3361,7 +3068,7 @@ function installAction(options, deps = {}) {
3361
3068
  withKarpathyHook: options.withKarpathyHook === true
3362
3069
  },
3363
3070
  cli: validated.cli,
3364
- projectDir: resolve3(options.projectDir ?? process.cwd()),
3071
+ projectDir: resolve2(options.projectDir ?? process.cwd()),
3365
3072
  scope: resolveScopeOption(options.scope, err)
3366
3073
  };
3367
3074
  executeSpec(spec, {
@@ -3430,7 +3137,7 @@ function defaultRunPipeline(spec, harnessRoot, mode, callbacks) {
3430
3137
  return runInstall(ctx);
3431
3138
  }
3432
3139
  function defaultHarnessRoot() {
3433
- return resolve3(fileURLToPath2(new URL(".", import.meta.url)), "..");
3140
+ return resolve2(fileURLToPath(new URL(".", import.meta.url)), "..");
3434
3141
  }
3435
3142
  function registerInstallCommand(cli2) {
3436
3143
  cli2.command("install", "Install harness assets into a project").option("--track <name>", "[Track] Track to install (repeatable)", { type: [String] }).option(
@@ -3465,15 +3172,15 @@ function registerInstallCommand(cli2) {
3465
3172
  // src/commands/uninstall.ts
3466
3173
  init_esm_shims();
3467
3174
  import { spawnSync as spawnSync2 } from "child_process";
3468
- import { existsSync as existsSync14, readFileSync as readFileSync13, rmSync } from "fs";
3469
- import { join as join13, resolve as resolve4 } from "path";
3175
+ import { existsSync as existsSync13, readFileSync as readFileSync12, rmSync } from "fs";
3176
+ import { join as join12, resolve as resolve3 } from "path";
3470
3177
  function uninstallAction(options, deps = {}) {
3471
3178
  const log = deps.log ?? console.log;
3472
3179
  const err = deps.err ?? console.error;
3473
3180
  const exit = deps.exit ?? ((code) => process.exit(code));
3474
3181
  const spawn = deps.spawn ?? defaultSpawn2;
3475
3182
  const rm = deps.rm ?? defaultRm;
3476
- const projectDir = resolve4(options.projectDir ?? process.cwd());
3183
+ const projectDir = resolve3(options.projectDir ?? process.cwd());
3477
3184
  const installLog = readInstallLog(projectDir);
3478
3185
  if (!installLog) {
3479
3186
  err(status.failure(c.red(`ERROR: install log not found at ${installLogPath(projectDir)}`)));
@@ -3638,22 +3345,22 @@ function buildGlobalAdvisoryCmd(asset) {
3638
3345
  }
3639
3346
  }
3640
3347
  function removeTemplates(log, projectDir, rm) {
3641
- rm(join13(projectDir, log.templates.claudeDir));
3642
- if (log.templates.codexDir) rm(join13(projectDir, log.templates.codexDir));
3643
- if (log.templates.opencodeDir) rm(join13(projectDir, log.templates.opencodeDir));
3348
+ rm(join12(projectDir, log.templates.claudeDir));
3349
+ if (log.templates.codexDir) rm(join12(projectDir, log.templates.codexDir));
3350
+ if (log.templates.opencodeDir) rm(join12(projectDir, log.templates.opencodeDir));
3644
3351
  const rootMd = log.templates.rootClaudeMd;
3645
3352
  if (rootMd) {
3646
3353
  if (rootClaudeMdModified(log, projectDir)) return { rootClaudeMdKept: true };
3647
- rm(join13(projectDir, rootMd.path));
3354
+ rm(join12(projectDir, rootMd.path));
3648
3355
  }
3649
3356
  return { rootClaudeMdKept: false };
3650
3357
  }
3651
3358
  function rootClaudeMdModified(log, projectDir) {
3652
3359
  const rootMd = log.templates.rootClaudeMd;
3653
3360
  if (!rootMd) return false;
3654
- const path = join13(projectDir, rootMd.path);
3655
- if (!existsSync14(path)) return false;
3656
- return hashContent(readFileSync13(path, "utf8")) !== rootMd.sha256;
3361
+ const path = join12(projectDir, rootMd.path);
3362
+ if (!existsSync13(path)) return false;
3363
+ return hashContent(readFileSync12(path, "utf8")) !== rootMd.sha256;
3657
3364
  }
3658
3365
  function formatTemplateList(log) {
3659
3366
  const items = [log.templates.claudeDir];
@@ -3665,7 +3372,7 @@ function defaultSpawn2(cmd, args) {
3665
3372
  return spawnSync2(cmd, [...args], { encoding: "utf8", stdio: "pipe", timeout: 12e4 });
3666
3373
  }
3667
3374
  function defaultRm(path) {
3668
- if (existsSync14(path)) {
3375
+ if (existsSync13(path)) {
3669
3376
  rmSync(path, { recursive: true, force: true });
3670
3377
  }
3671
3378
  }
@@ -4959,8 +4666,8 @@ Proceed?`,
4959
4666
 
4960
4667
  // src/state.ts
4961
4668
  init_esm_shims();
4962
- import { existsSync as existsSync15, readFileSync as readFileSync14 } from "fs";
4963
- import { join as join14 } from "path";
4669
+ import { existsSync as existsSync14, readFileSync as readFileSync13 } from "fs";
4670
+ import { join as join13 } from "path";
4964
4671
  var META_FILE = ".claude/.installed-tracks";
4965
4672
  var LEGACY_SIGNATURES = [
4966
4673
  { rule: "htmx.md", track: "ssr-htmx" },
@@ -4970,13 +4677,13 @@ var LEGACY_SIGNATURES = [
4970
4677
  { rule: "cli-development.md", track: "tooling" }
4971
4678
  ];
4972
4679
  function detectInstallState(projectDir) {
4973
- const claudeDir = join14(projectDir, ".claude");
4974
- const hasClaudeDir = existsSync15(claudeDir);
4680
+ const claudeDir = join13(projectDir, ".claude");
4681
+ const hasClaudeDir = existsSync14(claudeDir);
4975
4682
  if (!hasClaudeDir) {
4976
4683
  return { state: "new", tracks: [], source: "none", hasClaudeDir: false };
4977
4684
  }
4978
- const metaPath = join14(projectDir, META_FILE);
4979
- if (existsSync15(metaPath)) {
4685
+ const metaPath = join13(projectDir, META_FILE);
4686
+ if (existsSync14(metaPath)) {
4980
4687
  const tracks2 = readMetafile(metaPath);
4981
4688
  return { state: "existing", tracks: tracks2, source: "metafile", hasClaudeDir: true };
4982
4689
  }
@@ -4984,7 +4691,7 @@ function detectInstallState(projectDir) {
4984
4691
  return { state: "existing", tracks, source: "legacy", hasClaudeDir: true };
4985
4692
  }
4986
4693
  function readMetafile(path) {
4987
- const raw = readFileSync14(path, "utf8");
4694
+ const raw = readFileSync13(path, "utf8");
4988
4695
  const seen = /* @__PURE__ */ new Set();
4989
4696
  for (const line of raw.split(/\s+/)) {
4990
4697
  const trimmed = line.trim();
@@ -4995,13 +4702,13 @@ function readMetafile(path) {
4995
4702
  return [...seen].sort();
4996
4703
  }
4997
4704
  function inferFromLegacySignatures(projectDir) {
4998
- const rulesDir = join14(projectDir, ".claude/rules");
4999
- if (!existsSync15(rulesDir)) {
4705
+ const rulesDir = join13(projectDir, ".claude/rules");
4706
+ if (!existsSync14(rulesDir)) {
5000
4707
  return [];
5001
4708
  }
5002
4709
  const found = /* @__PURE__ */ new Set();
5003
4710
  for (const sig of LEGACY_SIGNATURES) {
5004
- if (existsSync15(join14(rulesDir, sig.rule))) {
4711
+ if (existsSync14(join13(rulesDir, sig.rule))) {
5005
4712
  found.add(sig.track);
5006
4713
  }
5007
4714
  }
@@ -5214,7 +4921,10 @@ function formatSummary(spec) {
5214
4921
  for (const [cat, ids] of groupAssetsByCategory(finalAssets)) {
5215
4922
  lines.push(` \xB7 ${cat}: ${ids.join(", ")}`);
5216
4923
  }
5217
- const cost = formatContextCostLine(summarizeContextCost(finalAssets));
4924
+ const cost = formatResidentCostLine(
4925
+ residentCost(buildManifest(spec).filter((e2) => e2.applies(spec))),
4926
+ summarizeContextCost(finalAssets).unmeasuredCount
4927
+ );
5218
4928
  if (cost) lines.push(` \xB7 ${cost}`);
5219
4929
  }
5220
4930
  if (spec.userOverride) {