@uzysjung/agent-harness 26.101.0 → 26.103.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.md +25 -2
- package/dist/{chunk-S3SQJRYD.js → chunk-4QB5UQDP.js} +71 -1
- package/dist/chunk-4QB5UQDP.js.map +1 -0
- package/dist/index.js +154 -90
- 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/dist/chunk-S3SQJRYD.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -2,20 +2,29 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CATEGORIES,
|
|
4
4
|
CATEGORY_TITLES,
|
|
5
|
+
CLI_BASES,
|
|
6
|
+
DEFAULT_OPTIONS,
|
|
5
7
|
DEV_METHOD_SKILL_IDS,
|
|
6
8
|
EXTERNAL_ASSETS,
|
|
7
9
|
INTERNAL_BUNDLED_SKILL_IDS,
|
|
10
|
+
TRACKS,
|
|
8
11
|
__commonJS,
|
|
9
12
|
__toESM,
|
|
10
13
|
anyTrack,
|
|
14
|
+
assetCliSupport,
|
|
15
|
+
assetReachesCli,
|
|
11
16
|
assetTrustTier,
|
|
12
17
|
experimentalOptInCandidates,
|
|
13
18
|
filterApplicableAssets,
|
|
14
19
|
hasDevTrack,
|
|
15
20
|
hasUiTrack,
|
|
16
21
|
init_esm_shims,
|
|
17
|
-
isAssetSelected
|
|
18
|
-
|
|
22
|
+
isAssetSelected,
|
|
23
|
+
isCliBase,
|
|
24
|
+
isInstallScope,
|
|
25
|
+
isTrack,
|
|
26
|
+
resolveScope
|
|
27
|
+
} from "./chunk-4QB5UQDP.js";
|
|
19
28
|
|
|
20
29
|
// node_modules/sisteransi/src/index.js
|
|
21
30
|
var require_src = __commonJS({
|
|
@@ -700,7 +709,7 @@ var cac = (name = "") => new CAC(name);
|
|
|
700
709
|
// package.json
|
|
701
710
|
var package_default = {
|
|
702
711
|
name: "@uzysjung/agent-harness",
|
|
703
|
-
version: "26.
|
|
712
|
+
version: "26.103.0",
|
|
704
713
|
description: "Curate vetted AI-coding skills & plugins by your tech stack \u2014 install only what you need, across Claude Code, Codex, OpenCode & Antigravity",
|
|
705
714
|
type: "module",
|
|
706
715
|
publishConfig: {
|
|
@@ -754,47 +763,11 @@ var package_default = {
|
|
|
754
763
|
|
|
755
764
|
// src/commands/install.ts
|
|
756
765
|
init_esm_shims();
|
|
757
|
-
import { resolve as
|
|
766
|
+
import { resolve as resolve3 } from "path";
|
|
767
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
758
768
|
|
|
759
769
|
// src/cli-targets.ts
|
|
760
770
|
init_esm_shims();
|
|
761
|
-
|
|
762
|
-
// src/types.ts
|
|
763
|
-
init_esm_shims();
|
|
764
|
-
var TRACKS = [
|
|
765
|
-
"tooling",
|
|
766
|
-
"csr-supabase",
|
|
767
|
-
"csr-fastify",
|
|
768
|
-
"csr-fastapi",
|
|
769
|
-
"ssr-htmx",
|
|
770
|
-
"ssr-nextjs",
|
|
771
|
-
"data",
|
|
772
|
-
"executive",
|
|
773
|
-
"full",
|
|
774
|
-
"project-management",
|
|
775
|
-
"growth-marketing"
|
|
776
|
-
];
|
|
777
|
-
function isTrack(value) {
|
|
778
|
-
return typeof value === "string" && TRACKS.includes(value);
|
|
779
|
-
}
|
|
780
|
-
var CLI_BASES = ["claude", "codex", "opencode", "antigravity"];
|
|
781
|
-
function isCliBase(value) {
|
|
782
|
-
return typeof value === "string" && CLI_BASES.includes(value);
|
|
783
|
-
}
|
|
784
|
-
var INSTALL_SCOPES = ["project", "global"];
|
|
785
|
-
function isInstallScope(value) {
|
|
786
|
-
return typeof value === "string" && INSTALL_SCOPES.includes(value);
|
|
787
|
-
}
|
|
788
|
-
function resolveScope(scope) {
|
|
789
|
-
return scope ?? "project";
|
|
790
|
-
}
|
|
791
|
-
var DEFAULT_OPTIONS = {
|
|
792
|
-
withPrune: false,
|
|
793
|
-
withCodexTrust: false,
|
|
794
|
-
withKarpathyHook: false
|
|
795
|
-
};
|
|
796
|
-
|
|
797
|
-
// src/cli-targets.ts
|
|
798
771
|
var CLI_BASE_SORT_ORDER = {
|
|
799
772
|
claude: 0,
|
|
800
773
|
codex: 1,
|
|
@@ -1497,6 +1470,15 @@ import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync6 }
|
|
|
1497
1470
|
import { homedir as homedir2 } from "os";
|
|
1498
1471
|
import { join as join6 } from "path";
|
|
1499
1472
|
var DEFAULT_SPAWN_TIMEOUT_MS = 12e4;
|
|
1473
|
+
function selectExternalTargets(assets, ctx) {
|
|
1474
|
+
const conditionPassed = filterApplicableAssets(assets, ctx).filter(
|
|
1475
|
+
(a) => a.method.kind !== "internal"
|
|
1476
|
+
);
|
|
1477
|
+
return {
|
|
1478
|
+
targets: conditionPassed.filter((a) => assetReachesCli(a, ctx.cli)),
|
|
1479
|
+
excludedByCli: conditionPassed.filter((a) => !assetReachesCli(a, ctx.cli))
|
|
1480
|
+
};
|
|
1481
|
+
}
|
|
1500
1482
|
function runExternalInstall(ctx, deps = {}) {
|
|
1501
1483
|
const log = deps.log ?? console.log;
|
|
1502
1484
|
const warn = deps.warn ?? console.error;
|
|
@@ -1504,9 +1486,7 @@ function runExternalInstall(ctx, deps = {}) {
|
|
|
1504
1486
|
const assets = deps.assets ?? EXTERNAL_ASSETS;
|
|
1505
1487
|
const harnessRoot = deps.harnessRoot ?? process.cwd();
|
|
1506
1488
|
const projectDir = ctx.projectDir ?? process.cwd();
|
|
1507
|
-
const applicable =
|
|
1508
|
-
(a) => a.method.kind !== "internal"
|
|
1509
|
-
);
|
|
1489
|
+
const { targets: applicable, excludedByCli } = selectExternalTargets(assets, ctx);
|
|
1510
1490
|
const sorted = [...applicable].sort((a, b2) => {
|
|
1511
1491
|
const ai = CATEGORIES.indexOf(a.category);
|
|
1512
1492
|
const bi = CATEGORIES.indexOf(b2.category);
|
|
@@ -1533,7 +1513,8 @@ function runExternalInstall(ctx, deps = {}) {
|
|
|
1533
1513
|
return {
|
|
1534
1514
|
attempted,
|
|
1535
1515
|
succeeded: attempted.filter((r) => r.ok).length,
|
|
1536
|
-
skipped: attempted.filter((r) => !r.ok).length
|
|
1516
|
+
skipped: attempted.filter((r) => !r.ok).length,
|
|
1517
|
+
excludedByCli
|
|
1537
1518
|
};
|
|
1538
1519
|
}
|
|
1539
1520
|
function installOne(asset, ctx) {
|
|
@@ -2612,7 +2593,10 @@ function runExternalPhase(ctx) {
|
|
|
2612
2593
|
options: spec.options,
|
|
2613
2594
|
...spec.userOverride ? { userOverride: spec.userOverride } : {}
|
|
2614
2595
|
};
|
|
2615
|
-
const applicableCount =
|
|
2596
|
+
const applicableCount = selectExternalTargets(EXTERNAL_ASSETS, {
|
|
2597
|
+
...filterCtx,
|
|
2598
|
+
cli: spec.cli
|
|
2599
|
+
}).targets.length;
|
|
2616
2600
|
ctx.onProgress?.({ type: "external-start", assetCount: applicableCount });
|
|
2617
2601
|
const external = runExt(
|
|
2618
2602
|
{ ...filterCtx, cli: spec.cli, projectDir, ...spec.scope ? { scope: spec.scope } : {} },
|
|
@@ -2736,6 +2720,54 @@ function listHookFiles(hookDir) {
|
|
|
2736
2720
|
// src/commands/install-render.ts
|
|
2737
2721
|
init_esm_shims();
|
|
2738
2722
|
|
|
2723
|
+
// src/context-cost.ts
|
|
2724
|
+
init_esm_shims();
|
|
2725
|
+
import { existsSync as existsSync12, readFileSync as readFileSync12 } from "fs";
|
|
2726
|
+
import { join as join11, resolve as resolve2 } from "path";
|
|
2727
|
+
import { fileURLToPath } from "url";
|
|
2728
|
+
var CHARS_PER_TOKEN = 4;
|
|
2729
|
+
function estimateTokens(chars) {
|
|
2730
|
+
return Math.ceil(chars / CHARS_PER_TOKEN);
|
|
2731
|
+
}
|
|
2732
|
+
function resolveBundleRoot() {
|
|
2733
|
+
return resolve2(fileURLToPath(new URL(".", import.meta.url)), "..");
|
|
2734
|
+
}
|
|
2735
|
+
function extractFrontmatter(content) {
|
|
2736
|
+
const m = content.match(/^?---\r?\n([\s\S]*?)\r?\n---/);
|
|
2737
|
+
return m?.[1] ?? null;
|
|
2738
|
+
}
|
|
2739
|
+
function assetDescriptorTokens(assetId, root = resolveBundleRoot()) {
|
|
2740
|
+
const asset = EXTERNAL_ASSETS.find((a) => a.id === assetId);
|
|
2741
|
+
if (!asset || asset.method.kind !== "internal") return null;
|
|
2742
|
+
const skillMd = join11(root, "templates", "skills", asset.method.key, "SKILL.md");
|
|
2743
|
+
if (!existsSync12(skillMd)) return null;
|
|
2744
|
+
const fm = extractFrontmatter(readFileSync12(skillMd, "utf8"));
|
|
2745
|
+
return fm === null ? null : estimateTokens(fm.length);
|
|
2746
|
+
}
|
|
2747
|
+
function summarizeContextCost(assetIds, root = resolveBundleRoot()) {
|
|
2748
|
+
let measuredTokens = 0;
|
|
2749
|
+
let measuredCount = 0;
|
|
2750
|
+
let unmeasuredCount = 0;
|
|
2751
|
+
for (const id of assetIds) {
|
|
2752
|
+
const tokens = assetDescriptorTokens(id, root);
|
|
2753
|
+
if (tokens === null) unmeasuredCount += 1;
|
|
2754
|
+
else {
|
|
2755
|
+
measuredTokens += tokens;
|
|
2756
|
+
measuredCount += 1;
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
return { measuredTokens, measuredCount, unmeasuredCount };
|
|
2760
|
+
}
|
|
2761
|
+
function formatContextCostLine(s) {
|
|
2762
|
+
if (s.measuredCount === 0 && s.unmeasuredCount === 0) return null;
|
|
2763
|
+
if (s.measuredCount === 0) {
|
|
2764
|
+
return `session-start context cost: unmeasured (${s.unmeasuredCount} external asset${s.unmeasuredCount === 1 ? "" : "s"})`;
|
|
2765
|
+
}
|
|
2766
|
+
const skills = `${s.measuredCount} bundled skill${s.measuredCount === 1 ? "" : "s"} measured`;
|
|
2767
|
+
const external = s.unmeasuredCount > 0 ? ` \xB7 ${s.unmeasuredCount} external unmeasured` : "";
|
|
2768
|
+
return `session-start context cost: ~${s.measuredTokens} tokens (${skills}${external})`;
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2739
2771
|
// src/preset-recommend.ts
|
|
2740
2772
|
init_esm_shims();
|
|
2741
2773
|
function recommendedExternalAssets(presets) {
|
|
@@ -2791,10 +2823,17 @@ function renderInstallHeader(log, spec, mode) {
|
|
|
2791
2823
|
log(infoRow("OPTIONS", formatOptions(spec)));
|
|
2792
2824
|
const finalAssets = finalSelectedAssets(spec.tracks, spec.userOverride);
|
|
2793
2825
|
if (finalAssets.length > 0) {
|
|
2794
|
-
|
|
2826
|
+
const unreachable = finalAssets.filter((id) => {
|
|
2827
|
+
const asset = EXTERNAL_ASSETS.find((a) => a.id === id);
|
|
2828
|
+
return asset ? !assetReachesCli(asset, spec.cli) : false;
|
|
2829
|
+
});
|
|
2830
|
+
const label = unreachable.length > 0 ? `${finalAssets.length} selected (${unreachable.length} outside [${spec.cli.join(", ")}] reach \u2014 not installed)` : `${finalAssets.length} selected`;
|
|
2831
|
+
log(infoRow("ASSETS", label));
|
|
2795
2832
|
for (const [cat, ids] of groupAssetsByCategory(finalAssets)) {
|
|
2796
2833
|
log(` ${c.dim(`\xB7 ${cat}:`)} ${ids.join(", ")}`);
|
|
2797
2834
|
}
|
|
2835
|
+
const cost = formatContextCostLine(summarizeContextCost(finalAssets));
|
|
2836
|
+
if (cost) log(` ${c.dim(`\xB7 ${cost}`)}`);
|
|
2798
2837
|
}
|
|
2799
2838
|
log("");
|
|
2800
2839
|
}
|
|
@@ -2804,12 +2843,32 @@ function createInstallRenderer(log, spec, verbose) {
|
|
|
2804
2843
|
const callbacks = {
|
|
2805
2844
|
onProgress: (event) => {
|
|
2806
2845
|
if (event.type === "baseline-complete") {
|
|
2807
|
-
const
|
|
2808
|
-
|
|
2846
|
+
const claudeSelected = targetsInclude(spec.cli, "claude");
|
|
2847
|
+
const eccWillInstall = claudeSelected && (isAssetSelected("ecc-plugin", spec) || spec.options.withPrune === true);
|
|
2848
|
+
renderPhase1Rows(log, event.baseline, verbose, eccWillInstall, claudeSelected);
|
|
2809
2849
|
} else if (event.type === "external-start" && event.assetCount > 0) {
|
|
2810
2850
|
log(unifiedSection(`External assets (${event.assetCount})`));
|
|
2811
2851
|
log("");
|
|
2812
2852
|
phase2HeaderPrinted = true;
|
|
2853
|
+
} else if (event.type === "external-complete") {
|
|
2854
|
+
const excluded = event.report.excludedByCli;
|
|
2855
|
+
if (excluded.length > 0) {
|
|
2856
|
+
if (!phase2HeaderPrinted) {
|
|
2857
|
+
log(unifiedSection("External assets (0)"));
|
|
2858
|
+
phase2HeaderPrinted = true;
|
|
2859
|
+
}
|
|
2860
|
+
const bySupport = /* @__PURE__ */ new Map();
|
|
2861
|
+
for (const a of excluded) {
|
|
2862
|
+
const key = assetCliSupport(a).join("/");
|
|
2863
|
+
bySupport.set(key, [...bySupport.get(key) ?? [], a.id]);
|
|
2864
|
+
}
|
|
2865
|
+
log("");
|
|
2866
|
+
for (const [support, ids] of bySupport) {
|
|
2867
|
+
log(
|
|
2868
|
+
` ${c.dim(`\xB7 ${ids.length} asset(s) not installed \u2014 requires ${support}, selected [${spec.cli.join(", ")}]: ${ids.join(", ")}`)}`
|
|
2869
|
+
);
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2813
2872
|
}
|
|
2814
2873
|
},
|
|
2815
2874
|
externalDeps: {
|
|
@@ -2917,22 +2976,17 @@ function renderFinalSummary(log, spec, report, fromWizard) {
|
|
|
2917
2976
|
)
|
|
2918
2977
|
);
|
|
2919
2978
|
}
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
infoRow(
|
|
2929
|
-
"NOTE",
|
|
2930
|
-
c.dim(
|
|
2931
|
-
`${claudeOnlyPlugins.length} plugin asset${claudeOnlyPlugins.length > 1 ? "s" : ""} are Claude Code-only \u2014 not installed for ${nonClaudeCli.map((b2) => CLI_SUMMARY_LABELS[b2]).join("/")}: ${claudeOnlyPlugins.map((a) => a.id).join(", ")}`
|
|
2932
|
-
)
|
|
2979
|
+
if (report.external && report.external.excludedByCli.length > 0) {
|
|
2980
|
+
const excluded = report.external.excludedByCli;
|
|
2981
|
+
log("");
|
|
2982
|
+
log(
|
|
2983
|
+
infoRow(
|
|
2984
|
+
"EXCLUDED",
|
|
2985
|
+
c.dim(
|
|
2986
|
+
`${excluded.length} asset${excluded.length > 1 ? "s" : ""} not installed \u2014 outside [${spec.cli.join(", ")}] reach: ${excluded.map((a) => a.id).join(", ")}`
|
|
2933
2987
|
)
|
|
2934
|
-
)
|
|
2935
|
-
|
|
2988
|
+
)
|
|
2989
|
+
);
|
|
2936
2990
|
}
|
|
2937
2991
|
if (!fromWizard) {
|
|
2938
2992
|
const optIn = experimentalOptInCandidates(spec);
|
|
@@ -2992,7 +3046,7 @@ function formatAssetMeta(asset, version) {
|
|
|
2992
3046
|
return `internal \xB7 templates (${m.key})`;
|
|
2993
3047
|
}
|
|
2994
3048
|
}
|
|
2995
|
-
function renderPhase1Rows(log, baseline, verbose = false, withEcc = false) {
|
|
3049
|
+
function renderPhase1Rows(log, baseline, verbose = false, withEcc = false, claudeSelected = true) {
|
|
2996
3050
|
if (baseline.updateMode) {
|
|
2997
3051
|
if (baseline.backup) {
|
|
2998
3052
|
log(assetRow("success", "backup", shortenPath(baseline.backup)));
|
|
@@ -3115,7 +3169,9 @@ function renderPhase1Rows(log, baseline, verbose = false, withEcc = false) {
|
|
|
3115
3169
|
log(
|
|
3116
3170
|
` ${c.dim("\xB7")} ${c.dim("ECC plugin not selected \u2014 cherry-pick fallback active (up to 4 agents + 8 skills + 3 commands)")}`
|
|
3117
3171
|
);
|
|
3118
|
-
|
|
3172
|
+
if (claudeSelected) {
|
|
3173
|
+
log(` ${c.dim("\xB7")} ${c.dim("Use --with ecc-plugin to install ECC plugin instead")}`);
|
|
3174
|
+
}
|
|
3119
3175
|
}
|
|
3120
3176
|
if (baseline.envFiles.envExampleCreated) {
|
|
3121
3177
|
log(assetRow("success", ".env.example", "Supabase token guide"));
|
|
@@ -3243,7 +3299,7 @@ function installAction(options, deps = {}) {
|
|
|
3243
3299
|
withKarpathyHook: options.withKarpathyHook === true
|
|
3244
3300
|
},
|
|
3245
3301
|
cli: validated.cli,
|
|
3246
|
-
projectDir:
|
|
3302
|
+
projectDir: resolve3(options.projectDir ?? process.cwd()),
|
|
3247
3303
|
scope: resolveScopeOption(options.scope, err)
|
|
3248
3304
|
};
|
|
3249
3305
|
executeSpec(spec, {
|
|
@@ -3312,7 +3368,7 @@ function defaultRunPipeline(spec, harnessRoot, mode, callbacks) {
|
|
|
3312
3368
|
return runInstall(ctx);
|
|
3313
3369
|
}
|
|
3314
3370
|
function defaultHarnessRoot() {
|
|
3315
|
-
return
|
|
3371
|
+
return resolve3(fileURLToPath2(new URL(".", import.meta.url)), "..");
|
|
3316
3372
|
}
|
|
3317
3373
|
function registerInstallCommand(cli2) {
|
|
3318
3374
|
cli2.command("install", "Install harness assets into a project").option("--track <name>", "[Track] Track to install (repeatable)", { type: [String] }).option(
|
|
@@ -3347,15 +3403,15 @@ function registerInstallCommand(cli2) {
|
|
|
3347
3403
|
// src/commands/uninstall.ts
|
|
3348
3404
|
init_esm_shims();
|
|
3349
3405
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
3350
|
-
import { existsSync as
|
|
3351
|
-
import { join as
|
|
3406
|
+
import { existsSync as existsSync13, readFileSync as readFileSync13, rmSync } from "fs";
|
|
3407
|
+
import { join as join12, resolve as resolve4 } from "path";
|
|
3352
3408
|
function uninstallAction(options, deps = {}) {
|
|
3353
3409
|
const log = deps.log ?? console.log;
|
|
3354
3410
|
const err = deps.err ?? console.error;
|
|
3355
3411
|
const exit = deps.exit ?? ((code) => process.exit(code));
|
|
3356
3412
|
const spawn = deps.spawn ?? defaultSpawn2;
|
|
3357
3413
|
const rm = deps.rm ?? defaultRm;
|
|
3358
|
-
const projectDir =
|
|
3414
|
+
const projectDir = resolve4(options.projectDir ?? process.cwd());
|
|
3359
3415
|
const installLog = readInstallLog(projectDir);
|
|
3360
3416
|
if (!installLog) {
|
|
3361
3417
|
err(status.failure(c.red(`ERROR: install log not found at ${installLogPath(projectDir)}`)));
|
|
@@ -3520,22 +3576,22 @@ function buildGlobalAdvisoryCmd(asset) {
|
|
|
3520
3576
|
}
|
|
3521
3577
|
}
|
|
3522
3578
|
function removeTemplates(log, projectDir, rm) {
|
|
3523
|
-
rm(
|
|
3524
|
-
if (log.templates.codexDir) rm(
|
|
3525
|
-
if (log.templates.opencodeDir) rm(
|
|
3579
|
+
rm(join12(projectDir, log.templates.claudeDir));
|
|
3580
|
+
if (log.templates.codexDir) rm(join12(projectDir, log.templates.codexDir));
|
|
3581
|
+
if (log.templates.opencodeDir) rm(join12(projectDir, log.templates.opencodeDir));
|
|
3526
3582
|
const rootMd = log.templates.rootClaudeMd;
|
|
3527
3583
|
if (rootMd) {
|
|
3528
3584
|
if (rootClaudeMdModified(log, projectDir)) return { rootClaudeMdKept: true };
|
|
3529
|
-
rm(
|
|
3585
|
+
rm(join12(projectDir, rootMd.path));
|
|
3530
3586
|
}
|
|
3531
3587
|
return { rootClaudeMdKept: false };
|
|
3532
3588
|
}
|
|
3533
3589
|
function rootClaudeMdModified(log, projectDir) {
|
|
3534
3590
|
const rootMd = log.templates.rootClaudeMd;
|
|
3535
3591
|
if (!rootMd) return false;
|
|
3536
|
-
const path =
|
|
3537
|
-
if (!
|
|
3538
|
-
return hashContent(
|
|
3592
|
+
const path = join12(projectDir, rootMd.path);
|
|
3593
|
+
if (!existsSync13(path)) return false;
|
|
3594
|
+
return hashContent(readFileSync13(path, "utf8")) !== rootMd.sha256;
|
|
3539
3595
|
}
|
|
3540
3596
|
function formatTemplateList(log) {
|
|
3541
3597
|
const items = [log.templates.claudeDir];
|
|
@@ -3547,7 +3603,7 @@ function defaultSpawn2(cmd, args) {
|
|
|
3547
3603
|
return spawnSync2(cmd, [...args], { encoding: "utf8", stdio: "pipe", timeout: 12e4 });
|
|
3548
3604
|
}
|
|
3549
3605
|
function defaultRm(path) {
|
|
3550
|
-
if (
|
|
3606
|
+
if (existsSync13(path)) {
|
|
3551
3607
|
rmSync(path, { recursive: true, force: true });
|
|
3552
3608
|
}
|
|
3553
3609
|
}
|
|
@@ -4841,8 +4897,8 @@ Proceed?`,
|
|
|
4841
4897
|
|
|
4842
4898
|
// src/state.ts
|
|
4843
4899
|
init_esm_shims();
|
|
4844
|
-
import { existsSync as
|
|
4845
|
-
import { join as
|
|
4900
|
+
import { existsSync as existsSync14, readFileSync as readFileSync14 } from "fs";
|
|
4901
|
+
import { join as join13 } from "path";
|
|
4846
4902
|
var META_FILE = ".claude/.installed-tracks";
|
|
4847
4903
|
var LEGACY_SIGNATURES = [
|
|
4848
4904
|
{ rule: "htmx.md", track: "ssr-htmx" },
|
|
@@ -4852,13 +4908,13 @@ var LEGACY_SIGNATURES = [
|
|
|
4852
4908
|
{ rule: "cli-development.md", track: "tooling" }
|
|
4853
4909
|
];
|
|
4854
4910
|
function detectInstallState(projectDir) {
|
|
4855
|
-
const claudeDir =
|
|
4856
|
-
const hasClaudeDir =
|
|
4911
|
+
const claudeDir = join13(projectDir, ".claude");
|
|
4912
|
+
const hasClaudeDir = existsSync14(claudeDir);
|
|
4857
4913
|
if (!hasClaudeDir) {
|
|
4858
4914
|
return { state: "new", tracks: [], source: "none", hasClaudeDir: false };
|
|
4859
4915
|
}
|
|
4860
|
-
const metaPath =
|
|
4861
|
-
if (
|
|
4916
|
+
const metaPath = join13(projectDir, META_FILE);
|
|
4917
|
+
if (existsSync14(metaPath)) {
|
|
4862
4918
|
const tracks2 = readMetafile(metaPath);
|
|
4863
4919
|
return { state: "existing", tracks: tracks2, source: "metafile", hasClaudeDir: true };
|
|
4864
4920
|
}
|
|
@@ -4866,7 +4922,7 @@ function detectInstallState(projectDir) {
|
|
|
4866
4922
|
return { state: "existing", tracks, source: "legacy", hasClaudeDir: true };
|
|
4867
4923
|
}
|
|
4868
4924
|
function readMetafile(path) {
|
|
4869
|
-
const raw =
|
|
4925
|
+
const raw = readFileSync14(path, "utf8");
|
|
4870
4926
|
const seen = /* @__PURE__ */ new Set();
|
|
4871
4927
|
for (const line of raw.split(/\s+/)) {
|
|
4872
4928
|
const trimmed = line.trim();
|
|
@@ -4877,13 +4933,13 @@ function readMetafile(path) {
|
|
|
4877
4933
|
return [...seen].sort();
|
|
4878
4934
|
}
|
|
4879
4935
|
function inferFromLegacySignatures(projectDir) {
|
|
4880
|
-
const rulesDir =
|
|
4881
|
-
if (!
|
|
4936
|
+
const rulesDir = join13(projectDir, ".claude/rules");
|
|
4937
|
+
if (!existsSync14(rulesDir)) {
|
|
4882
4938
|
return [];
|
|
4883
4939
|
}
|
|
4884
4940
|
const found = /* @__PURE__ */ new Set();
|
|
4885
4941
|
for (const sig of LEGACY_SIGNATURES) {
|
|
4886
|
-
if (
|
|
4942
|
+
if (existsSync14(join13(rulesDir, sig.rule))) {
|
|
4887
4943
|
found.add(sig.track);
|
|
4888
4944
|
}
|
|
4889
4945
|
}
|
|
@@ -5086,10 +5142,18 @@ function formatSummary(spec) {
|
|
|
5086
5142
|
];
|
|
5087
5143
|
const finalAssets = finalSelectedAssets(spec.tracks, spec.userOverride);
|
|
5088
5144
|
if (finalAssets.length > 0) {
|
|
5089
|
-
|
|
5145
|
+
const unreachable = finalAssets.filter((id) => {
|
|
5146
|
+
const asset = EXTERNAL_ASSETS.find((a) => a.id === id);
|
|
5147
|
+
return asset ? !assetReachesCli(asset, spec.cli) : false;
|
|
5148
|
+
});
|
|
5149
|
+
lines.push(
|
|
5150
|
+
unreachable.length > 0 ? `Assets: ${finalAssets.length} selected (${unreachable.length} outside [${spec.cli.join(", ")}] reach \u2014 not installed)` : `Assets: ${finalAssets.length} selected`
|
|
5151
|
+
);
|
|
5090
5152
|
for (const [cat, ids] of groupAssetsByCategory(finalAssets)) {
|
|
5091
5153
|
lines.push(` \xB7 ${cat}: ${ids.join(", ")}`);
|
|
5092
5154
|
}
|
|
5155
|
+
const cost = formatContextCostLine(summarizeContextCost(finalAssets));
|
|
5156
|
+
if (cost) lines.push(` \xB7 ${cost}`);
|
|
5093
5157
|
}
|
|
5094
5158
|
if (spec.userOverride) {
|
|
5095
5159
|
if (spec.userOverride.forceInclude.length > 0) {
|