@sunasteriskrnd/takumi 1.0.0-dev.49 → 1.0.0-dev.50

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.
Files changed (2) hide show
  1. package/dist/index.js +2099 -268
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -19815,7 +19815,7 @@ var package_default;
19815
19815
  var init_package = __esm(() => {
19816
19816
  package_default = {
19817
19817
  name: "@sunasteriskrnd/takumi",
19818
- version: "1.0.0-dev.49",
19818
+ version: "1.0.0-dev.50",
19819
19819
  description: "CLI tool for bootstrapping and managing Takumi projects",
19820
19820
  type: "module",
19821
19821
  repository: {
@@ -20011,7 +20011,7 @@ function getLegacyManifestPath(providerRoot) {
20011
20011
  return join4(providerRoot, LEGACY_MANIFEST_FILENAME);
20012
20012
  }
20013
20013
  function getCliVersion() {
20014
- return process.env.TAKUMI_CLI_VERSION?.trim() || process.env.npm_package_version?.trim() || "unknown";
20014
+ return "1.0.0-dev.50"?.trim() || process.env.npm_package_version?.trim() || "unknown";
20015
20015
  }
20016
20016
  function getCliUserAgent() {
20017
20017
  return `${TAKUMI_CLI_NPM_PACKAGE_NAME}/${getCliVersion()}`;
@@ -22249,6 +22249,7 @@ var init_kit = __esm(() => {
22249
22249
  ".mcp.json",
22250
22250
  ".tkmignore",
22251
22251
  ".skignore",
22252
+ "takumi.json",
22252
22253
  ".takumi.json"
22253
22254
  ];
22254
22255
  PROTECTED_PATTERNS = [...NEVER_COPY_PATTERNS, ...USER_CONFIG_PATTERNS];
@@ -22515,7 +22516,7 @@ function normalizeTakumiConfigInput(value) {
22515
22516
  }
22516
22517
  return normalized;
22517
22518
  }
22518
- var PlanValidationModeSchema, PlanFocusAreaSchema, PlanResolutionOrderSchema, ProjectTypeSchema, PackageManagerSchema, FrameworkSchema, GEMINI_MODEL_VALUES, LEGACY_GEMINI_MODEL_ALIASES, GeminiModelSchema, StatuslineModeSchema, StatuslineSectionIdSchema, StatuslineSectionConfigSchema, StatuslineThemeSchema, StatuslineLayoutSchema, CodingLevelSchema, PlanResolutionSchema, PlanValidationSchema, SkPlanConfigSchema, SkDocsConfigSchema, SkPathsConfigSchema, SkLocaleConfigSchema, SkTrustConfigSchema, SkGraphifyConfigSchema, SkProjectConfigSchema, SkGeminiConfigSchema, SkSkillsConfigSchema, SkSkillExtensionsConfigSchema, UpdatePipelineSchema, ResolvedModelConfigSchema, ModelTierMapSchema, SkModelTaxonomySchema, SkAssertionSchema, SkHooksConfigSchema, TakumiConfigSchema, DEFAULT_TAKUMI_CONFIG, TAKUMI_HOOK_NAMES;
22519
+ var PlanValidationModeSchema, PlanFocusAreaSchema, PlanResolutionOrderSchema, ProjectTypeSchema, PackageManagerSchema, FrameworkSchema, GEMINI_MODEL_VALUES, LEGACY_GEMINI_MODEL_ALIASES, GeminiModelSchema, StatuslineModeSchema, StatuslineSectionIdSchema, StatuslineSectionConfigSchema, StatuslineThemeSchema, StatuslineLayoutSchema, StatuslineBarStyleSchema, StatuslineConfigSchema, CodingLevelSchema, PlanResolutionSchema, PlanValidationSchema, SkPlanConfigSchema, SkDocsConfigSchema, SkPathsConfigSchema, SkLocaleConfigSchema, SkTrustConfigSchema, SkGraphifyConfigSchema, SkProjectConfigSchema, SkGeminiConfigSchema, SkSkillsConfigSchema, SkSkillExtensionsConfigSchema, UpdatePipelineSchema, ResolvedModelConfigSchema, ModelTierMapSchema, SkModelTaxonomySchema, SkAssertionSchema, SkHooksConfigSchema, TakumiConfigSchema, DEFAULT_TAKUMI_CONFIG, TAKUMI_HOOK_NAMES;
22519
22520
  var init_takumi_config = __esm(() => {
22520
22521
  init_zod();
22521
22522
  PlanValidationModeSchema = exports_external.enum(["prompt", "auto", "strict", "none"]);
@@ -22603,6 +22604,50 @@ var init_takumi_config = __esm(() => {
22603
22604
  maxAgentRows: exports_external.number().int().min(1).max(10).default(4),
22604
22605
  todoTruncation: exports_external.number().int().min(20).max(100).default(50)
22605
22606
  });
22607
+ StatuslineBarStyleSchema = exports_external.enum(["geometric", "block"]);
22608
+ StatuslineConfigSchema = exports_external.object({
22609
+ prompt: exports_external.string().optional(),
22610
+ brand: exports_external.object({
22611
+ icon: exports_external.string().optional(),
22612
+ showCliVersion: exports_external.boolean().optional(),
22613
+ showCoreVersion: exports_external.boolean().optional(),
22614
+ color: exports_external.string().optional(),
22615
+ versionColor: exports_external.string().optional()
22616
+ }).passthrough().optional(),
22617
+ model: exports_external.object({ color: exports_external.string().optional() }).passthrough().optional(),
22618
+ context: exports_external.object({
22619
+ barWidth: exports_external.number().int().optional(),
22620
+ barStyle: StatuslineBarStyleSchema.optional(),
22621
+ showPercent: exports_external.boolean().optional(),
22622
+ colors: exports_external.object({ low: exports_external.string(), mid: exports_external.string(), high: exports_external.string() }).partial().passthrough().optional(),
22623
+ thresholds: exports_external.object({ mid: exports_external.number(), high: exports_external.number() }).partial().passthrough().optional()
22624
+ }).passthrough().optional(),
22625
+ quotas: exports_external.object({
22626
+ windows: exports_external.array(exports_external.string()).optional(),
22627
+ barWidth: exports_external.number().int().optional(),
22628
+ showCountdown: exports_external.boolean().optional(),
22629
+ icon: exports_external.string().optional()
22630
+ }).passthrough().optional(),
22631
+ directory: exports_external.object({
22632
+ icon: exports_external.string().optional(),
22633
+ collapseHome: exports_external.boolean().optional(),
22634
+ truncationLength: exports_external.number().int().optional(),
22635
+ color: exports_external.string().optional()
22636
+ }).passthrough().optional(),
22637
+ git: exports_external.object({
22638
+ icon: exports_external.string().optional(),
22639
+ showDirty: exports_external.boolean().optional(),
22640
+ dirtyInBrackets: exports_external.boolean().optional(),
22641
+ showAheadBehind: exports_external.boolean().optional(),
22642
+ countUntracked: exports_external.boolean().optional(),
22643
+ branchColor: exports_external.string().optional()
22644
+ }).passthrough().optional(),
22645
+ activity: exports_external.object({
22646
+ maxAgentRows: exports_external.number().int().optional(),
22647
+ todoTruncation: exports_external.number().int().optional()
22648
+ }).passthrough().optional(),
22649
+ cost: exports_external.object({ icon: exports_external.string().optional(), hideZero: exports_external.boolean().optional() }).passthrough().optional()
22650
+ }).passthrough();
22606
22651
  CodingLevelSchema = exports_external.number().int().min(-1).max(5);
22607
22652
  PlanResolutionSchema = exports_external.object({
22608
22653
  order: exports_external.array(PlanResolutionOrderSchema).optional(),
@@ -22689,7 +22734,7 @@ var init_takumi_config = __esm(() => {
22689
22734
  TakumiConfigSchema = exports_external.object({
22690
22735
  $schema: exports_external.string().optional(),
22691
22736
  codingLevel: CodingLevelSchema.optional(),
22692
- statusline: StatuslineModeSchema.optional(),
22737
+ statusline: exports_external.union([StatuslineModeSchema, StatuslineConfigSchema]).optional(),
22693
22738
  statuslineColors: exports_external.boolean().optional(),
22694
22739
  statuslineQuota: exports_external.boolean().optional(),
22695
22740
  statuslineLayout: StatuslineLayoutSchema.optional(),
@@ -24713,6 +24758,22 @@ var init_manifest_tracker = __esm(() => {
24713
24758
  });
24714
24759
 
24715
24760
  // src/services/file-operations/manifest/index.ts
24761
+ var exports_manifest = {};
24762
+ __export(exports_manifest, {
24763
+ writeManifest: () => writeManifest,
24764
+ writeKitPending: () => writeKitPending,
24765
+ trackFilesWithProgress: () => trackFilesWithProgress,
24766
+ removeKitFromManifest: () => removeKitFromManifest,
24767
+ readManifest: () => readManifest,
24768
+ readKitManifest: () => readKitManifest,
24769
+ getUninstallManifest: () => getUninstallManifest,
24770
+ findPendingKits: () => findPendingKits,
24771
+ findManifestPathSync: () => findManifestPathSync,
24772
+ findManifestPath: () => findManifestPath,
24773
+ findFileInInstalledKits: () => findFileInInstalledKits,
24774
+ buildFileTrackingList: () => buildFileTrackingList,
24775
+ ManifestTracker: () => ManifestTracker
24776
+ });
24716
24777
  var init_manifest = __esm(() => {
24717
24778
  init_manifest_reader();
24718
24779
  init_manifest_tracker();
@@ -45575,14 +45636,26 @@ class TakumiConfigManager {
45575
45636
  static getGlobalConfigDir() {
45576
45637
  return join62(homedir18(), ".claude");
45577
45638
  }
45639
+ static resolveConfigPath(dir) {
45640
+ const preferred = join62(dir, TAKUMI_CONFIG_FILE);
45641
+ if (existsSync26(preferred))
45642
+ return preferred;
45643
+ const legacy = join62(dir, LEGACY_TAKUMI_CONFIG_FILE);
45644
+ if (existsSync26(legacy))
45645
+ return legacy;
45646
+ return preferred;
45647
+ }
45648
+ static configFileExistsIn(dir) {
45649
+ return existsSync26(join62(dir, TAKUMI_CONFIG_FILE)) || existsSync26(join62(dir, LEGACY_TAKUMI_CONFIG_FILE));
45650
+ }
45578
45651
  static getGlobalConfigPath() {
45579
- return join62(TakumiConfigManager.getGlobalConfigDir(), TAKUMI_CONFIG_FILE);
45652
+ return TakumiConfigManager.resolveConfigPath(TakumiConfigManager.getGlobalConfigDir());
45580
45653
  }
45581
45654
  static getProjectConfigDir(projectDir) {
45582
45655
  return join62(projectDir, ".claude");
45583
45656
  }
45584
45657
  static getProjectConfigPath(projectDir) {
45585
- return join62(TakumiConfigManager.getProjectConfigDir(projectDir), TAKUMI_CONFIG_FILE);
45658
+ return TakumiConfigManager.resolveConfigPath(TakumiConfigManager.getProjectConfigDir(projectDir));
45586
45659
  }
45587
45660
  static async loadConfigFile(configPath) {
45588
45661
  try {
@@ -45676,8 +45749,8 @@ class TakumiConfigManager {
45676
45749
  return TakumiConfigManager.loadConfigFile(TakumiConfigManager.getProjectConfigPath(projectDir));
45677
45750
  }
45678
45751
  static projectConfigExists(dir, isGlobal) {
45679
- const configPath = isGlobal ? join62(dir, ".takumi.json") : TakumiConfigManager.getProjectConfigPath(dir);
45680
- return existsSync26(configPath);
45752
+ const searchDir = isGlobal ? dir : TakumiConfigManager.getProjectConfigDir(dir);
45753
+ return TakumiConfigManager.configFileExistsIn(searchDir);
45681
45754
  }
45682
45755
  static configExists(scope, projectDir) {
45683
45756
  if (scope === "global") {
@@ -45699,7 +45772,7 @@ class TakumiConfigManager {
45699
45772
  await TakumiConfigManager.saveFull(existing, scope, projectDir);
45700
45773
  }
45701
45774
  }
45702
- var TAKUMI_CONFIG_FILE = ".takumi.json", DANGEROUS_KEYS;
45775
+ var TAKUMI_CONFIG_FILE = "takumi.json", LEGACY_TAKUMI_CONFIG_FILE = ".takumi.json", DANGEROUS_KEYS;
45703
45776
  var init_takumi_config_manager = __esm(() => {
45704
45777
  init_logger();
45705
45778
  init_types2();
@@ -49666,19 +49739,305 @@ var require_parse4 = __commonJS((exports, module) => {
49666
49739
  };
49667
49740
  });
49668
49741
 
49742
+ // src/domains/statusline/cache-dir.ts
49743
+ import {
49744
+ closeSync as closeSync5,
49745
+ constants as fsConstants3,
49746
+ fstatSync,
49747
+ mkdirSync as mkdirSync5,
49748
+ openSync as openSync8,
49749
+ readSync as readSync5,
49750
+ renameSync as renameSync3,
49751
+ rmSync as rmSync3,
49752
+ writeFileSync as writeFileSync9
49753
+ } from "node:fs";
49754
+ import { join as join102 } from "node:path";
49755
+ function getStatuslineCacheDir() {
49756
+ return join102(getConfigDir(), "cache", "statusline");
49757
+ }
49758
+ function getStatuslineCachePath(fileName) {
49759
+ return join102(getStatuslineCacheDir(), fileName);
49760
+ }
49761
+ function ensureStatuslineCacheDir() {
49762
+ try {
49763
+ mkdirSync5(getStatuslineCacheDir(), { recursive: true, mode: 448 });
49764
+ return true;
49765
+ } catch {
49766
+ return false;
49767
+ }
49768
+ }
49769
+ function readCacheFileSafe(path10) {
49770
+ let fd;
49771
+ try {
49772
+ fd = openSync8(path10, fsConstants3.O_RDONLY | fsConstants3.O_NOFOLLOW);
49773
+ const stat9 = fstatSync(fd);
49774
+ if (!stat9.isFile())
49775
+ return null;
49776
+ const uid = typeof process.getuid === "function" ? process.getuid() : undefined;
49777
+ if (uid !== undefined && stat9.uid !== uid)
49778
+ return null;
49779
+ const size = stat9.size;
49780
+ if (size <= 0)
49781
+ return "";
49782
+ const buf = Buffer.allocUnsafe(size);
49783
+ let read = 0;
49784
+ while (read < size) {
49785
+ const n2 = readSync5(fd, buf, read, size - read, read);
49786
+ if (n2 <= 0)
49787
+ break;
49788
+ read += n2;
49789
+ }
49790
+ return buf.toString("utf8", 0, read);
49791
+ } catch {
49792
+ return null;
49793
+ } finally {
49794
+ if (fd !== undefined) {
49795
+ try {
49796
+ closeSync5(fd);
49797
+ } catch {}
49798
+ }
49799
+ }
49800
+ }
49801
+ function writeCacheFileSafe(path10, data) {
49802
+ if (!ensureStatuslineCacheDir())
49803
+ return false;
49804
+ const tmpPath = `${path10}.tmp.${process.pid}.${++writeCounter2}`;
49805
+ try {
49806
+ writeFileSync9(tmpPath, data, { mode: 384 });
49807
+ renameSync3(tmpPath, path10);
49808
+ return true;
49809
+ } catch {
49810
+ try {
49811
+ rmSync3(tmpPath, { force: true });
49812
+ } catch {}
49813
+ return false;
49814
+ }
49815
+ }
49816
+ var writeCounter2 = 0;
49817
+ var init_cache_dir = __esm(() => {
49818
+ init_paths2();
49819
+ });
49820
+
49821
+ // src/domains/hooks/handlers/usage-cache/usage-credential.ts
49822
+ import { execFileSync as execFileSync6 } from "node:child_process";
49823
+ import { closeSync as closeSync6, constants as fsConstants4, fstatSync as fstatSync2, openSync as openSync9, readFileSync as readFileSync18 } from "node:fs";
49824
+ import { homedir as homedir28, platform as platform10 } from "node:os";
49825
+ import { join as join111 } from "node:path";
49826
+ function hasAnthropicRuntimeOverride(env2 = process.env) {
49827
+ return OVERRIDE_ENV_KEYS.some((key) => {
49828
+ const value = env2[key];
49829
+ return typeof value === "string" && value.trim().length > 0;
49830
+ });
49831
+ }
49832
+ function lowerTrimmed(value) {
49833
+ return typeof value === "string" ? value.trim().toLowerCase() : "";
49834
+ }
49835
+ function parseOAuth(raw) {
49836
+ if (!raw || typeof raw !== "object")
49837
+ return null;
49838
+ const bag = raw.claudeAiOauth;
49839
+ if (!bag || typeof bag !== "object")
49840
+ return null;
49841
+ const oauth = bag;
49842
+ const token = typeof oauth.accessToken === "string" ? oauth.accessToken.trim() : "";
49843
+ if (!token)
49844
+ return null;
49845
+ return {
49846
+ accessToken: token,
49847
+ subscriptionType: lowerTrimmed(oauth.subscriptionType),
49848
+ rateLimitTier: lowerTrimmed(oauth.rateLimitTier)
49849
+ };
49850
+ }
49851
+ function readTrustedFile(path10) {
49852
+ let fd;
49853
+ try {
49854
+ fd = openSync9(path10, fsConstants4.O_RDONLY | fsConstants4.O_NOFOLLOW);
49855
+ const stat9 = fstatSync2(fd);
49856
+ if (!stat9.isFile())
49857
+ return null;
49858
+ const uid = typeof process.getuid === "function" ? process.getuid() : undefined;
49859
+ if (uid !== undefined && stat9.uid !== uid)
49860
+ return null;
49861
+ if ((stat9.mode & 18) !== 0)
49862
+ return null;
49863
+ return readFileSync18(fd, "utf8");
49864
+ } catch {
49865
+ return null;
49866
+ } finally {
49867
+ if (fd !== undefined) {
49868
+ try {
49869
+ closeSync6(fd);
49870
+ } catch {}
49871
+ }
49872
+ }
49873
+ }
49874
+ function fromCredentialsFile() {
49875
+ const raw = readTrustedFile(join111(homedir28(), ".claude", ".credentials.json"));
49876
+ if (!raw)
49877
+ return null;
49878
+ try {
49879
+ return parseOAuth(JSON.parse(raw));
49880
+ } catch {
49881
+ return null;
49882
+ }
49883
+ }
49884
+ function fromKeychain() {
49885
+ if (platform10() !== "darwin")
49886
+ return null;
49887
+ try {
49888
+ const out = execFileSync6("security", ["find-generic-password", "-s", KEYCHAIN_SERVICE, "-w"], {
49889
+ timeout: 5000,
49890
+ encoding: "utf8",
49891
+ stdio: ["ignore", "pipe", "ignore"]
49892
+ });
49893
+ return parseOAuth(JSON.parse(out.trim()));
49894
+ } catch {
49895
+ return null;
49896
+ }
49897
+ }
49898
+ function isPaidSubscription(oauth) {
49899
+ const sub = oauth.subscriptionType;
49900
+ const hasPaidPlan = sub.length > 0 && sub !== "free" && sub !== "none";
49901
+ return hasPaidPlan || PAID_TIER_PATTERN.test(oauth.rateLimitTier);
49902
+ }
49903
+ function resolveUsageAccess() {
49904
+ if (hasAnthropicRuntimeOverride()) {
49905
+ return { eligible: false, note: "runtime-override", accessToken: null };
49906
+ }
49907
+ const oauth = fromKeychain() ?? fromCredentialsFile();
49908
+ if (!oauth) {
49909
+ return { eligible: false, note: "missing-credentials", accessToken: null };
49910
+ }
49911
+ if (!isPaidSubscription(oauth)) {
49912
+ return { eligible: false, note: "non-subscription-auth", accessToken: null };
49913
+ }
49914
+ return { eligible: true, note: "eligible", accessToken: oauth.accessToken };
49915
+ }
49916
+ var OVERRIDE_ENV_KEYS, PAID_TIER_PATTERN, KEYCHAIN_SERVICE = "Claude Code-credentials";
49917
+ var init_usage_credential = __esm(() => {
49918
+ OVERRIDE_ENV_KEYS = [
49919
+ "ANTHROPIC_BASE_URL",
49920
+ "ANTHROPIC_AUTH_TOKEN",
49921
+ "ANTHROPIC_API_KEY"
49922
+ ];
49923
+ PAID_TIER_PATTERN = /claude|max|pro|team|enterprise/;
49924
+ });
49925
+
49926
+ // src/domains/hooks/handlers/usage-cache/usage-limits-cache.ts
49927
+ var exports_usage_limits_cache = {};
49928
+ __export(exports_usage_limits_cache, {
49929
+ refreshUsageCache: () => refreshUsageCache,
49930
+ readUsageCache: () => readUsageCache,
49931
+ normalizeUtilization: () => normalizeUtilization,
49932
+ isUsageCacheFresh: () => isUsageCacheFresh,
49933
+ getCacheAgeMs: () => getCacheAgeMs
49934
+ });
49935
+ function cachePath() {
49936
+ return getStatuslineCachePath(USAGE_CACHE_FILE);
49937
+ }
49938
+ function readUsageCache() {
49939
+ const raw = readCacheFileSafe(cachePath());
49940
+ if (!raw)
49941
+ return null;
49942
+ try {
49943
+ return JSON.parse(raw);
49944
+ } catch {
49945
+ return null;
49946
+ }
49947
+ }
49948
+ function getCacheAgeMs(cache3, now = Date.now()) {
49949
+ if (!cache3 || typeof cache3.timestamp !== "number")
49950
+ return Number.POSITIVE_INFINITY;
49951
+ return Math.max(0, now - cache3.timestamp);
49952
+ }
49953
+ function isUsageCacheFresh(cache3, maxAgeMs, now = Date.now()) {
49954
+ return getCacheAgeMs(cache3, now) <= maxAgeMs;
49955
+ }
49956
+ function normalizeUtilization(utilization) {
49957
+ if (typeof utilization !== "number" || !Number.isFinite(utilization))
49958
+ return null;
49959
+ if (utilization > 0 && utilization < 1)
49960
+ return Math.round(utilization * 100);
49961
+ return Math.max(0, Math.round(utilization));
49962
+ }
49963
+ function buildSnapshot(data, now) {
49964
+ if (!data)
49965
+ return null;
49966
+ return {
49967
+ sourceVersion: SNAPSHOT_VERSION,
49968
+ fetchedAt: new Date(now).toISOString(),
49969
+ fiveHourPercent: normalizeUtilization(data.five_hour?.utilization),
49970
+ weekPercent: normalizeUtilization(data.seven_day?.utilization)
49971
+ };
49972
+ }
49973
+ function persist(status2, data) {
49974
+ const now = Date.now();
49975
+ const cache3 = {
49976
+ timestamp: now,
49977
+ status: status2,
49978
+ data,
49979
+ snapshot: status2 === "available" ? buildSnapshot(data, now) : null
49980
+ };
49981
+ writeCacheFileSafe(cachePath(), JSON.stringify(cache3));
49982
+ }
49983
+ async function fetchUsage() {
49984
+ const access3 = resolveUsageAccess();
49985
+ if (!access3.eligible || !access3.accessToken) {
49986
+ return { status: "unavailable", note: access3.note, data: null };
49987
+ }
49988
+ const controller = new AbortController;
49989
+ const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
49990
+ try {
49991
+ const response = await fetch(USAGE_ENDPOINT, {
49992
+ method: "GET",
49993
+ headers: {
49994
+ Accept: "application/json",
49995
+ "Content-Type": "application/json",
49996
+ Authorization: `Bearer ${access3.accessToken}`,
49997
+ "anthropic-beta": OAUTH_BETA_HEADER,
49998
+ "User-Agent": USER_AGENT
49999
+ },
50000
+ signal: controller.signal
50001
+ });
50002
+ if (!response.ok) {
50003
+ return { status: "unavailable", note: `http-${response.status}`, data: null };
50004
+ }
50005
+ const body = await response.json();
50006
+ if (!body || typeof body !== "object") {
50007
+ return { status: "unavailable", note: "invalid-body", data: null };
50008
+ }
50009
+ return { status: "available", note: "fetched", data: body };
50010
+ } catch (err) {
50011
+ const aborted = err instanceof Error && err.name === "AbortError";
50012
+ return { status: "unavailable", note: aborted ? "timeout" : "fetch-failed", data: null };
50013
+ } finally {
50014
+ clearTimeout(timer);
50015
+ }
50016
+ }
50017
+ async function refreshUsageCache() {
50018
+ const outcome = await fetchUsage();
50019
+ persist(outcome.status, outcome.data);
50020
+ return outcome.note;
50021
+ }
50022
+ var USAGE_ENDPOINT = "https://api.anthropic.com/api/oauth/usage", USER_AGENT = "takumi-agent-kit-engineer/usage-cache", FETCH_TIMEOUT_MS = 5000, USAGE_CACHE_FILE = "usage-limits.json", OAUTH_BETA_HEADER = "oauth-2025-04-20", SNAPSHOT_VERSION = 1;
50023
+ var init_usage_limits_cache = __esm(() => {
50024
+ init_cache_dir();
50025
+ init_usage_credential();
50026
+ });
50027
+
49669
50028
  // src/shared/monorepo-resolver.ts
49670
50029
  var exports_monorepo_resolver = {};
49671
50030
  __export(exports_monorepo_resolver, {
49672
50031
  resolveMonorepoRoot: () => resolveMonorepoRoot
49673
50032
  });
49674
- import { existsSync as existsSync56, readFileSync as readFileSync22 } from "node:fs";
49675
- import { dirname as dirname33, join as join118, resolve as resolve26 } from "node:path";
50033
+ import { existsSync as existsSync58, readFileSync as readFileSync23 } from "node:fs";
50034
+ import { dirname as dirname33, join as join121, resolve as resolve26 } from "node:path";
49676
50035
  import { fileURLToPath as fileURLToPath3 } from "node:url";
49677
50036
  function parseMetadataAt(metadataPath) {
49678
- if (!existsSync56(metadataPath))
50037
+ if (!existsSync58(metadataPath))
49679
50038
  return null;
49680
50039
  try {
49681
- const raw = readFileSync22(metadataPath, "utf-8");
50040
+ const raw = readFileSync23(metadataPath, "utf-8");
49682
50041
  const parsed = JSON.parse(raw);
49683
50042
  if (typeof parsed.name !== "string" || typeof parsed.version !== "string" || !ACCEPTED_METADATA_NAMES.has(parsed.name)) {
49684
50043
  return null;
@@ -49689,11 +50048,11 @@ function parseMetadataAt(metadataPath) {
49689
50048
  }
49690
50049
  }
49691
50050
  function readSourceDirFromPackageJson(candidateRoot) {
49692
- const packageJsonPath = join118(candidateRoot, "package.json");
49693
- if (!existsSync56(packageJsonPath))
50051
+ const packageJsonPath = join121(candidateRoot, "package.json");
50052
+ if (!existsSync58(packageJsonPath))
49694
50053
  return null;
49695
50054
  try {
49696
- const parsed = JSON.parse(readFileSync22(packageJsonPath, "utf-8"));
50055
+ const parsed = JSON.parse(readFileSync23(packageJsonPath, "utf-8"));
49697
50056
  const kitCfg = parsed.takumi;
49698
50057
  if (kitCfg && typeof kitCfg.sourceDir === "string" && kitCfg.sourceDir.length > 0) {
49699
50058
  return kitCfg.sourceDir;
@@ -49712,7 +50071,7 @@ function tryReadAtCandidate(candidateRoot) {
49712
50071
  };
49713
50072
  }
49714
50073
  const sourceDir = readSourceDirFromPackageJson(candidateRoot) ?? "claude";
49715
- const sourceRoot = join118(candidateRoot, sourceDir);
50074
+ const sourceRoot = join121(candidateRoot, sourceDir);
49716
50075
  const nestedMetadata = parseMetadataAt(getManifestPath(sourceRoot)) ?? parseMetadataAt(getLegacyManifestPath(sourceRoot));
49717
50076
  if (nestedMetadata) {
49718
50077
  return {
@@ -50442,7 +50801,7 @@ var init_help_commands = __esm(() => {
50442
50801
  });
50443
50802
 
50444
50803
  // src/domains/help/help-interactive.ts
50445
- import { spawn as spawn5 } from "node:child_process";
50804
+ import { spawn as spawn6 } from "node:child_process";
50446
50805
  import * as readline from "node:readline";
50447
50806
  function getTerminalHeight() {
50448
50807
  return process.stdout.rows || 24;
@@ -50477,7 +50836,7 @@ async function trySystemPager(content) {
50477
50836
  const pagerCmd = process.env.PAGER || "less";
50478
50837
  const pagerArgs = getPagerArgs(pagerCmd);
50479
50838
  try {
50480
- const pager = spawn5(pagerCmd, pagerArgs, {
50839
+ const pager = spawn6(pagerCmd, pagerArgs, {
50481
50840
  stdio: ["pipe", process.stdout, process.stderr],
50482
50841
  shell: false
50483
50842
  });
@@ -73292,13 +73651,538 @@ var metricsRecord = {
73292
73651
  }
73293
73652
  };
73294
73653
 
73654
+ // src/domains/statusline/activity-cache.ts
73655
+ import { readdirSync as readdirSync7, rmSync as rmSync4, statSync as statSync8 } from "node:fs";
73656
+ import { join as join103 } from "node:path";
73657
+
73658
+ // src/domains/statusline/activity-snapshot.ts
73659
+ import { existsSync as existsSync49 } from "node:fs";
73660
+
73661
+ // src/domains/statusline/transcript-parser.ts
73662
+ import { createReadStream as createReadStream4, existsSync as existsSync48 } from "node:fs";
73663
+ import { createInterface as createInterface2 } from "node:readline";
73664
+ var MAX_TOOLS = 20;
73665
+ var MAX_AGENTS = 10;
73666
+ var NATIVE_TASK = "native_task";
73667
+ var LEGACY_TODOWRITE = "legacy_todowrite";
73668
+ var BASH_TARGET_LIMIT = 30;
73669
+ var TASK_ID_PATTERN = /["']?task[_-]?id["']?\s*[:=]\s*["']([^"']+)["']/i;
73670
+ function asRecord2(value) {
73671
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
73672
+ }
73673
+ function stringOr(value, fallback2) {
73674
+ return typeof value === "string" ? value : fallback2;
73675
+ }
73676
+ function stringOrNull(value) {
73677
+ return typeof value === "string" ? value : null;
73678
+ }
73679
+ function extractTarget(toolName, input) {
73680
+ switch (toolName) {
73681
+ case "Read":
73682
+ case "Write":
73683
+ case "Edit":
73684
+ return stringOrNull(input.file_path) ?? stringOrNull(input.path);
73685
+ case "Glob":
73686
+ case "Grep":
73687
+ return stringOrNull(input.pattern);
73688
+ case "Bash": {
73689
+ const command = input.command;
73690
+ if (typeof command !== "string")
73691
+ return null;
73692
+ return command.length > BASH_TARGET_LIMIT ? `${command.slice(0, BASH_TARGET_LIMIT)}...` : command;
73693
+ }
73694
+ default:
73695
+ return null;
73696
+ }
73697
+ }
73698
+ function findEmbeddedTaskId(node) {
73699
+ if (node == null)
73700
+ return null;
73701
+ if (typeof node === "string") {
73702
+ try {
73703
+ const parsed = JSON.parse(node);
73704
+ if (parsed && typeof parsed === "object")
73705
+ return findEmbeddedTaskId(parsed);
73706
+ } catch {}
73707
+ const match = node.match(TASK_ID_PATTERN);
73708
+ return match ? match[1] : null;
73709
+ }
73710
+ if (Array.isArray(node)) {
73711
+ for (const item of node) {
73712
+ const found = findEmbeddedTaskId(item);
73713
+ if (found)
73714
+ return found;
73715
+ }
73716
+ return null;
73717
+ }
73718
+ if (typeof node === "object") {
73719
+ const obj = node;
73720
+ for (const key of ["taskId", "task_id"]) {
73721
+ const direct = obj[key];
73722
+ if (typeof direct === "string" || typeof direct === "number")
73723
+ return String(direct);
73724
+ }
73725
+ for (const value of Object.values(obj)) {
73726
+ const found = findEmbeddedTaskId(value);
73727
+ if (found)
73728
+ return found;
73729
+ }
73730
+ }
73731
+ return null;
73732
+ }
73733
+ function normalizeTodo(todo) {
73734
+ if (!todo || typeof todo !== "object")
73735
+ return null;
73736
+ const t = todo;
73737
+ const out = {
73738
+ content: typeof t.content === "string" ? t.content : "",
73739
+ status: typeof t.status === "string" ? t.status : "pending",
73740
+ activeForm: typeof t.activeForm === "string" ? t.activeForm : null
73741
+ };
73742
+ if (t.id != null)
73743
+ out.id = t.id;
73744
+ return out;
73745
+ }
73746
+ function emptyTranscript() {
73747
+ return {
73748
+ tools: [],
73749
+ agents: [],
73750
+ todos: [],
73751
+ sessionStart: null,
73752
+ statuslineActivityCount: 0,
73753
+ invalidLineCount: 0,
73754
+ lastValidEntryAt: null,
73755
+ lastActivityAt: null
73756
+ };
73757
+ }
73758
+ async function parseTranscript(transcriptPath) {
73759
+ if (!transcriptPath || !existsSync48(transcriptPath))
73760
+ return emptyTranscript();
73761
+ const tools = new Map;
73762
+ const agents = new Map;
73763
+ let todos = [];
73764
+ let sessionStart = null;
73765
+ let activityCount = 0;
73766
+ let invalidLines = 0;
73767
+ let lastValidEntryAt = null;
73768
+ let lastActivityAt = null;
73769
+ const applyTaskUpdate = (input) => {
73770
+ const { taskId, status: status2 } = input;
73771
+ if (!taskId || !status2)
73772
+ return;
73773
+ const taskIdStr = String(taskId);
73774
+ const natives = todos.filter((t) => t._source === NATIVE_TASK);
73775
+ let target = natives.find((t) => String(t.id) === taskIdStr);
73776
+ if (!target && /^\d+$/.test(taskIdStr)) {
73777
+ target = natives[Number.parseInt(taskIdStr, 10) - 1];
73778
+ }
73779
+ if (!target)
73780
+ return;
73781
+ target.status = String(status2);
73782
+ if ("activeForm" in input) {
73783
+ target.activeForm = typeof input.activeForm === "string" ? input.activeForm : null;
73784
+ }
73785
+ };
73786
+ const handleToolUse = (block, at) => {
73787
+ const id = block.id;
73788
+ const name2 = block.name;
73789
+ if (typeof id !== "string" || typeof name2 !== "string")
73790
+ return false;
73791
+ const input = asRecord2(block.input);
73792
+ switch (name2) {
73793
+ case "Task":
73794
+ agents.set(id, {
73795
+ id,
73796
+ type: stringOr(input.subagent_type, "unknown"),
73797
+ model: stringOrNull(input.model),
73798
+ description: stringOrNull(input.description),
73799
+ status: "running",
73800
+ startTime: at,
73801
+ endTime: null
73802
+ });
73803
+ return true;
73804
+ case "TodoWrite":
73805
+ if (Array.isArray(input.todos)) {
73806
+ todos = input.todos.map((raw) => ({ ...asRecord2(raw), _source: LEGACY_TODOWRITE }));
73807
+ }
73808
+ return true;
73809
+ case "TaskCreate":
73810
+ if (input.subject) {
73811
+ todos.push({
73812
+ id,
73813
+ content: String(input.subject),
73814
+ status: "pending",
73815
+ activeForm: input.activeForm ? String(input.activeForm) : null,
73816
+ _source: NATIVE_TASK,
73817
+ _toolUseId: id
73818
+ });
73819
+ }
73820
+ return true;
73821
+ case "TaskUpdate":
73822
+ applyTaskUpdate(input);
73823
+ return true;
73824
+ default:
73825
+ tools.set(id, {
73826
+ id,
73827
+ name: name2,
73828
+ target: extractTarget(name2, input),
73829
+ status: "running",
73830
+ startTime: at,
73831
+ endTime: null
73832
+ });
73833
+ return false;
73834
+ }
73835
+ };
73836
+ const handleToolResult = (block, at) => {
73837
+ const id = block.tool_use_id;
73838
+ if (typeof id !== "string")
73839
+ return false;
73840
+ const tool = tools.get(id);
73841
+ if (tool) {
73842
+ tool.status = block.is_error ? "error" : "completed";
73843
+ tool.endTime = at;
73844
+ }
73845
+ let agentActivity = false;
73846
+ const agent = agents.get(id);
73847
+ if (agent) {
73848
+ agent.status = "completed";
73849
+ agent.endTime = at;
73850
+ agentActivity = true;
73851
+ }
73852
+ const nativeTodo = todos.find((t) => t._source === NATIVE_TASK && t._toolUseId === id);
73853
+ if (nativeTodo) {
73854
+ const resolvedId = findEmbeddedTaskId(block.content);
73855
+ if (resolvedId)
73856
+ nativeTodo.id = resolvedId;
73857
+ }
73858
+ return agentActivity;
73859
+ };
73860
+ const processEntry = (entry) => {
73861
+ const rawTs = entry.timestamp;
73862
+ const parsed = rawTs == null ? new Date(Number.NaN) : new Date(rawTs);
73863
+ const hasValidTime = !Number.isNaN(parsed.getTime());
73864
+ const at = hasValidTime ? parsed : new Date;
73865
+ lastValidEntryAt = at.toISOString();
73866
+ if (sessionStart === null && hasValidTime)
73867
+ sessionStart = at;
73868
+ const content = asRecord2(entry.message).content;
73869
+ if (!Array.isArray(content))
73870
+ return;
73871
+ let activity = false;
73872
+ for (const rawBlock of content) {
73873
+ const block = asRecord2(rawBlock);
73874
+ if (block.type === "tool_use") {
73875
+ if (handleToolUse(block, at)) {
73876
+ activityCount++;
73877
+ activity = true;
73878
+ }
73879
+ } else if (block.type === "tool_result") {
73880
+ if (handleToolResult(block, at)) {
73881
+ activityCount++;
73882
+ activity = true;
73883
+ }
73884
+ }
73885
+ }
73886
+ if (activity)
73887
+ lastActivityAt = at.toISOString();
73888
+ };
73889
+ await new Promise((resolve21) => {
73890
+ let stream;
73891
+ try {
73892
+ stream = createReadStream4(transcriptPath, { encoding: "utf8" });
73893
+ } catch {
73894
+ resolve21();
73895
+ return;
73896
+ }
73897
+ stream.on("error", () => resolve21());
73898
+ const rl = createInterface2({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
73899
+ rl.on("line", (line) => {
73900
+ if (!line.trim())
73901
+ return;
73902
+ let entry;
73903
+ try {
73904
+ entry = JSON.parse(line);
73905
+ } catch {
73906
+ invalidLines++;
73907
+ return;
73908
+ }
73909
+ if (entry && typeof entry === "object")
73910
+ processEntry(entry);
73911
+ });
73912
+ rl.on("error", () => resolve21());
73913
+ rl.on("close", () => resolve21());
73914
+ });
73915
+ return {
73916
+ tools: Array.from(tools.values()).slice(-MAX_TOOLS),
73917
+ agents: Array.from(agents.values()).slice(-MAX_AGENTS),
73918
+ todos: todos.map(normalizeTodo).filter((t) => t !== null),
73919
+ sessionStart,
73920
+ statuslineActivityCount: activityCount,
73921
+ invalidLineCount: invalidLines,
73922
+ lastValidEntryAt,
73923
+ lastActivityAt
73924
+ };
73925
+ }
73926
+
73927
+ // src/domains/statusline/activity-snapshot.ts
73928
+ var MAX_AGENTS2 = 10;
73929
+ var WARM_SOURCES = new Set(["startup", "resume", "compact"]);
73930
+ function nowIso() {
73931
+ return new Date().toISOString();
73932
+ }
73933
+ function asRecord3(value) {
73934
+ return value && typeof value === "object" ? value : {};
73935
+ }
73936
+ function stringOr2(value, fallback2) {
73937
+ return typeof value === "string" && value ? value : fallback2;
73938
+ }
73939
+ function toIsoOrNull(value) {
73940
+ if (!value)
73941
+ return null;
73942
+ const date = value instanceof Date ? value : new Date(value);
73943
+ return Number.isNaN(date.getTime()) ? null : date.toISOString();
73944
+ }
73945
+ function isoOr(value, fallback2) {
73946
+ return toIsoOrNull(value) ?? fallback2;
73947
+ }
73948
+ function normalizeAgent(raw) {
73949
+ if (!raw || typeof raw !== "object")
73950
+ return null;
73951
+ const a3 = raw;
73952
+ return {
73953
+ id: a3.id != null ? String(a3.id) : null,
73954
+ type: stringOr2(a3.type, "unknown"),
73955
+ model: stringOr2(a3.model, null),
73956
+ description: stringOr2(a3.description, null),
73957
+ status: a3.status === "completed" ? "completed" : "running",
73958
+ startTime: toIsoOrNull(a3.startTime),
73959
+ endTime: toIsoOrNull(a3.endTime)
73960
+ };
73961
+ }
73962
+ function normalizeTodo2(raw) {
73963
+ if (!raw || typeof raw !== "object")
73964
+ return null;
73965
+ const t = raw;
73966
+ const todo = {
73967
+ content: stringOr2(t.content, ""),
73968
+ status: stringOr2(t.status, "pending"),
73969
+ activeForm: stringOr2(t.activeForm, null)
73970
+ };
73971
+ if (t.id != null)
73972
+ todo.id = String(t.id);
73973
+ return todo;
73974
+ }
73975
+ function createEmptyActivitySnapshot(now = nowIso()) {
73976
+ return { sessionStart: now, updatedAt: now, warmed: false, agents: [], todos: [] };
73977
+ }
73978
+ function sanitizeActivitySnapshot(snapshot) {
73979
+ const now = nowIso();
73980
+ if (!snapshot || typeof snapshot !== "object")
73981
+ return createEmptyActivitySnapshot(now);
73982
+ const s = snapshot;
73983
+ const rawAgents = Array.isArray(s.agents) ? s.agents : [];
73984
+ const rawTodos = Array.isArray(s.todos) ? s.todos : [];
73985
+ return {
73986
+ sessionStart: isoOr(s.sessionStart, now),
73987
+ updatedAt: isoOr(s.updatedAt, now),
73988
+ warmed: Boolean(s.warmed),
73989
+ agents: rawAgents.map(normalizeAgent).filter((a3) => a3 !== null).slice(-MAX_AGENTS2),
73990
+ todos: rawTodos.map(normalizeTodo2).filter((t) => t !== null)
73991
+ };
73992
+ }
73993
+ function applyStatuslineEvent(snapshot, input, now) {
73994
+ const base = sanitizeActivitySnapshot({ ...asRecord3(snapshot), updatedAt: now });
73995
+ if (input.hook_event_name !== "SubagentStop")
73996
+ return base;
73997
+ const agentId = input.agent_id != null ? String(input.agent_id) : null;
73998
+ const agentType = typeof input.agent_type === "string" ? input.agent_type : null;
73999
+ if (!agentId && !agentType)
74000
+ return base;
74001
+ for (let i = base.agents.length - 1;i >= 0; i--) {
74002
+ const agent = base.agents[i];
74003
+ const matchesId = agentId != null && agent.id === agentId;
74004
+ const matchesType = agentId == null && agentType != null && agent.status === "running" && agent.type === agentType;
74005
+ if (matchesId || matchesType) {
74006
+ agent.status = "completed";
74007
+ agent.endTime = agent.endTime || now;
74008
+ break;
74009
+ }
74010
+ }
74011
+ return base;
74012
+ }
74013
+ function shouldPreserveExistingSnapshot(existing, parsed, transcript) {
74014
+ if (!existing)
74015
+ return false;
74016
+ const existingHasActivity = existing.agents.length > 0 || existing.todos.length > 0;
74017
+ if (!existingHasActivity || existing.warmed !== true)
74018
+ return false;
74019
+ const existingAt = Date.parse(existing.updatedAt);
74020
+ const transcriptAt = Date.parse(transcript.lastActivityAt || transcript.lastValidEntryAt || "");
74021
+ const bothDated = Number.isFinite(existingAt) && Number.isFinite(transcriptAt);
74022
+ if (bothDated && existingAt >= transcriptAt)
74023
+ return true;
74024
+ if (transcript.invalidLineCount > 0) {
74025
+ if (!bothDated)
74026
+ return true;
74027
+ return existingAt >= transcriptAt;
74028
+ }
74029
+ const parsedHasActivity = parsed.agents.length > 0 || parsed.todos.length > 0;
74030
+ if (parsedHasActivity)
74031
+ return false;
74032
+ return transcript.statuslineActivityCount === 0;
74033
+ }
74034
+ function resolveTranscriptPath(input, cachedPath) {
74035
+ const fromInput = input.transcript_path;
74036
+ if (typeof fromInput === "string" && fromInput && existsSync49(fromInput))
74037
+ return fromInput;
74038
+ if (cachedPath && existsSync49(cachedPath))
74039
+ return cachedPath;
74040
+ return "";
74041
+ }
74042
+ function shouldWarmStatuslineCache(source, snapshot) {
74043
+ if (!source || !WARM_SOURCES.has(source))
74044
+ return false;
74045
+ return snapshot?.warmed !== true;
74046
+ }
74047
+ async function refreshActivitySnapshot(input, sessionId) {
74048
+ try {
74049
+ if (!sessionId)
74050
+ return;
74051
+ const now = nowIso();
74052
+ const existing = readActivity(sessionId);
74053
+ const current = existing?.snapshot ?? createEmptyActivitySnapshot(now);
74054
+ const existingPath = existing?.lastTranscriptPath ?? "";
74055
+ const transcriptPath = resolveTranscriptPath(input, existingPath);
74056
+ if (!transcriptPath) {
74057
+ const next2 = sanitizeActivitySnapshot(applyStatuslineEvent(current, input, now));
74058
+ writeActivity(sessionId, next2, existingPath);
74059
+ return;
74060
+ }
74061
+ const transcript = await parseTranscript(transcriptPath);
74062
+ const parsedSnapshot = applyStatuslineEvent({
74063
+ sessionStart: transcript.sessionStart?.toISOString() || current.sessionStart || now,
74064
+ updatedAt: now,
74065
+ warmed: true,
74066
+ agents: transcript.agents,
74067
+ todos: transcript.todos
74068
+ }, input, now);
74069
+ const preserve = shouldPreserveExistingSnapshot(current, parsedSnapshot, transcript);
74070
+ const next = sanitizeActivitySnapshot(preserve ? applyStatuslineEvent(current, input, now) : parsedSnapshot);
74071
+ writeActivity(sessionId, next, preserve && existingPath ? existingPath : transcriptPath);
74072
+ } catch {}
74073
+ }
74074
+
74075
+ // src/domains/statusline/activity-cache.ts
74076
+ init_cache_dir();
74077
+ var ACTIVITY_TTL_MS = 7 * 24 * 60 * 60 * 1000;
74078
+ var FILE_PREFIX = "statusline-activity-";
74079
+ var FILE_SUFFIX = ".json";
74080
+ var MAX_ID_LENGTH = 128;
74081
+ function fileNameFor(sessionId) {
74082
+ const safe = sessionId.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, MAX_ID_LENGTH);
74083
+ return `${FILE_PREFIX}${safe}${FILE_SUFFIX}`;
74084
+ }
74085
+ function readActivity(sessionId) {
74086
+ if (!sessionId)
74087
+ return null;
74088
+ const raw = readCacheFileSafe(getStatuslineCachePath(fileNameFor(sessionId)));
74089
+ if (!raw)
74090
+ return null;
74091
+ try {
74092
+ const parsed = JSON.parse(raw);
74093
+ return {
74094
+ snapshot: sanitizeActivitySnapshot(parsed.snapshot),
74095
+ lastTranscriptPath: typeof parsed.lastTranscriptPath === "string" ? parsed.lastTranscriptPath : ""
74096
+ };
74097
+ } catch {
74098
+ return null;
74099
+ }
74100
+ }
74101
+ function writeActivity(sessionId, snapshot, lastTranscriptPath) {
74102
+ if (!sessionId)
74103
+ return false;
74104
+ return writeCacheFileSafe(getStatuslineCachePath(fileNameFor(sessionId)), JSON.stringify({ snapshot, lastTranscriptPath }));
74105
+ }
74106
+ function cleanupStaleActivity(now = Date.now()) {
74107
+ let entries;
74108
+ try {
74109
+ entries = readdirSync7(getStatuslineCacheDir());
74110
+ } catch {
74111
+ return;
74112
+ }
74113
+ for (const entry of entries) {
74114
+ if (!entry.startsWith(FILE_PREFIX) || !entry.endsWith(FILE_SUFFIX))
74115
+ continue;
74116
+ const full = join103(getStatuslineCacheDir(), entry);
74117
+ try {
74118
+ if (now - statSync8(full).mtimeMs > ACTIVITY_TTL_MS)
74119
+ rmSync4(full, { force: true });
74120
+ } catch {}
74121
+ }
74122
+ }
74123
+
74124
+ // src/domains/hooks/handlers/session-activity/handler.ts
74125
+ var ENABLE_GATE_KEY = "session-state";
74126
+ var TRACKED_TOOLS = new Set([
74127
+ "Task",
74128
+ "TaskCreate",
74129
+ "TaskUpdate",
74130
+ "TodoWrite"
74131
+ ]);
74132
+ var RECORD_RESULT = { status: "record", timingMs: 0 };
74133
+ var NOOP_RESULT = { status: "no-op", timingMs: 0 };
74134
+ var sessionActivity = {
74135
+ name: "session-activity",
74136
+ category: "session",
74137
+ policy: "record",
74138
+ events: ["SessionStart", "PostToolUse", "Stop", "SubagentStop"],
74139
+ matchers: {
74140
+ SessionStart: "startup|resume|compact",
74141
+ PostToolUse: "Task|TaskCreate|TaskUpdate|TodoWrite"
74142
+ },
74143
+ async run(input, ctx) {
74144
+ try {
74145
+ if (!isHandlerEnabled(ctx, ENABLE_GATE_KEY))
74146
+ return NOOP_RESULT;
74147
+ const sessionId = ctx.sessionId;
74148
+ if (!sessionId)
74149
+ return RECORD_RESULT;
74150
+ switch (ctx.event) {
74151
+ case "SessionStart": {
74152
+ cleanupStaleActivity();
74153
+ const source = typeof input.source === "string" ? input.source : "";
74154
+ const existing = readActivity(sessionId)?.snapshot ?? null;
74155
+ if (shouldWarmStatuslineCache(source, existing)) {
74156
+ await refreshActivitySnapshot(input, sessionId);
74157
+ }
74158
+ return RECORD_RESULT;
74159
+ }
74160
+ case "PostToolUse": {
74161
+ const tool = typeof input.tool_name === "string" ? input.tool_name : "";
74162
+ if (TRACKED_TOOLS.has(tool))
74163
+ await refreshActivitySnapshot(input, sessionId);
74164
+ return RECORD_RESULT;
74165
+ }
74166
+ case "Stop":
74167
+ case "SubagentStop":
74168
+ await refreshActivitySnapshot(input, sessionId);
74169
+ return RECORD_RESULT;
74170
+ default:
74171
+ return NOOP_RESULT;
74172
+ }
74173
+ } catch {
74174
+ return NOOP_RESULT;
74175
+ }
74176
+ }
74177
+ };
74178
+
73295
74179
  // src/domains/hooks/handlers/session-init/handler.ts
73296
- import { mkdirSync as mkdirSync5 } from "node:fs";
73297
- import { dirname as dirname28, join as join105 } from "node:path";
74180
+ import { mkdirSync as mkdirSync6 } from "node:fs";
74181
+ import { dirname as dirname28, join as join107 } from "node:path";
73298
74182
 
73299
74183
  // src/domains/hooks/handlers/_shared/project-detector.ts
73300
- import { existsSync as existsSync48, readFileSync as readFileSync15 } from "node:fs";
73301
- import { join as join102 } from "node:path";
74184
+ import { existsSync as existsSync50, readFileSync as readFileSync15 } from "node:fs";
74185
+ import { join as join104 } from "node:path";
73302
74186
  var LOCKFILE_PRIORITY = [
73303
74187
  { manager: "bun", files: ["bun.lockb", "bun.lock"] },
73304
74188
  { manager: "pnpm", files: ["pnpm-lock.yaml"] },
@@ -73333,14 +74217,14 @@ var APP_FRAMEWORKS = new Set([
73333
74217
  var WORKSPACE_MARKER_FILES = ["pnpm-workspace.yaml", "turbo.json", "lerna.json"];
73334
74218
  function fileExists(cwd2, name2) {
73335
74219
  try {
73336
- return existsSync48(join102(cwd2, name2));
74220
+ return existsSync50(join104(cwd2, name2));
73337
74221
  } catch {
73338
74222
  return false;
73339
74223
  }
73340
74224
  }
73341
74225
  function readPackageJson(cwd2) {
73342
74226
  try {
73343
- const raw = readFileSync15(join102(cwd2, "package.json"), "utf8");
74227
+ const raw = readFileSync15(join104(cwd2, "package.json"), "utf8");
73344
74228
  const parsed = JSON.parse(raw);
73345
74229
  if (parsed && typeof parsed === "object")
73346
74230
  return parsed;
@@ -73424,26 +74308,26 @@ function detectProject(cwd2) {
73424
74308
  // src/domains/hooks/handlers/session-init/env-entries.ts
73425
74309
  import { createHash as createHash14 } from "node:crypto";
73426
74310
  import { platform as platform8, userInfo } from "node:os";
73427
- import { join as join104 } from "node:path";
74311
+ import { join as join106 } from "node:path";
73428
74312
 
73429
74313
  // src/domains/hooks/handlers/session-init/plan-resolver.ts
73430
- import { existsSync as existsSync49, readFileSync as readFileSync16, readdirSync as readdirSync7 } from "node:fs";
73431
- import { join as join103 } from "node:path";
74314
+ import { existsSync as existsSync51, readFileSync as readFileSync16, readdirSync as readdirSync8 } from "node:fs";
74315
+ import { join as join105 } from "node:path";
73432
74316
  var MAX_PLAN_DIRS = 100;
73433
74317
  var MAX_PLAN_FILE_BYTES = 64 * 1024;
73434
74318
  function listPlanDirs(plansPath) {
73435
74319
  try {
73436
- if (!existsSync49(plansPath))
74320
+ if (!existsSync51(plansPath))
73437
74321
  return [];
73438
- return readdirSync7(plansPath, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort().slice(0, MAX_PLAN_DIRS);
74322
+ return readdirSync8(plansPath, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort().slice(0, MAX_PLAN_DIRS);
73439
74323
  } catch {
73440
74324
  return [];
73441
74325
  }
73442
74326
  }
73443
74327
  function planFileMentionsSession(planDir, sessionId) {
73444
74328
  try {
73445
- const planFile = join103(planDir, "plan.md");
73446
- if (!existsSync49(planFile))
74329
+ const planFile = join105(planDir, "plan.md");
74330
+ if (!existsSync51(planFile))
73447
74331
  return false;
73448
74332
  const body = readFileSync16(planFile, { encoding: "utf8" });
73449
74333
  if (body.length > MAX_PLAN_FILE_BYTES)
@@ -73457,7 +74341,7 @@ function resolveActivePlan(plansPath, sessionId) {
73457
74341
  if (!sessionId)
73458
74342
  return "";
73459
74343
  for (const name2 of listPlanDirs(plansPath)) {
73460
- const dir = join103(plansPath, name2);
74344
+ const dir = join105(plansPath, name2);
73461
74345
  if (name2.includes(sessionId) || planFileMentionsSession(dir, sessionId)) {
73462
74346
  return dir;
73463
74347
  }
@@ -73478,7 +74362,7 @@ function resolveSuggestedPlan(plansPath, branch, branchPattern) {
73478
74362
  return "";
73479
74363
  for (const name2 of listPlanDirs(plansPath)) {
73480
74364
  if (name2.includes(slug))
73481
- return join103(plansPath, name2);
74365
+ return join105(plansPath, name2);
73482
74366
  }
73483
74367
  return "";
73484
74368
  }
@@ -73532,11 +74416,11 @@ function buildEnvEntries(params) {
73532
74416
  const plan = config.plan ?? {};
73533
74417
  const locale = config.locale ?? {};
73534
74418
  const validation = plan.validation ?? {};
73535
- const settingsDir = join104(projectRoot, ".claude");
73536
- const docsPath = join104(projectRoot, paths.docs ?? "docs");
73537
- const plansPath = join104(projectRoot, paths.plans ?? "plans");
74419
+ const settingsDir = join106(projectRoot, ".claude");
74420
+ const docsPath = join106(projectRoot, paths.docs ?? "docs");
74421
+ const plansPath = join106(projectRoot, paths.plans ?? "plans");
73538
74422
  const reportsDir = plan.reportsDir ?? "reports";
73539
- const reportsPath = join104(plansPath, reportsDir);
74423
+ const reportsPath = join106(plansPath, reportsDir);
73540
74424
  const namingFormat = plan.namingFormat ?? "";
73541
74425
  const activePlan = resolveActivePlan(plansPath, ctx.sessionId);
73542
74426
  const suggestedPlan = resolveSuggestedPlan(plansPath, branch, plan.resolution?.branchPattern ?? "");
@@ -73585,11 +74469,12 @@ function numberString(value) {
73585
74469
  // src/domains/hooks/handlers/session-init/git-facts.ts
73586
74470
  import { execFileSync as execFileSync2 } from "node:child_process";
73587
74471
  var GIT_TIMEOUT_MS = 800;
73588
- function runGit(cwd2, args) {
74472
+ var GIT_STATUS_TIMEOUT_MS = 500;
74473
+ function runGit(cwd2, args, timeoutMs = GIT_TIMEOUT_MS) {
73589
74474
  try {
73590
74475
  const out = execFileSync2("git", ["-C", cwd2, ...args], {
73591
74476
  encoding: "utf8",
73592
- timeout: GIT_TIMEOUT_MS,
74477
+ timeout: timeoutMs,
73593
74478
  stdio: ["ignore", "pipe", "ignore"]
73594
74479
  });
73595
74480
  return out.trim();
@@ -73597,13 +74482,20 @@ function runGit(cwd2, args) {
73597
74482
  return "";
73598
74483
  }
73599
74484
  }
73600
- function resolveGitRoot(cwd2) {
73601
- return runGit(cwd2, ["rev-parse", "--show-toplevel"]);
74485
+ function resolveGitRoot(cwd2, timeoutMs) {
74486
+ return runGit(cwd2, ["rev-parse", "--show-toplevel"], timeoutMs);
73602
74487
  }
73603
- function resolveGitBranch(cwd2) {
73604
- const branch = runGit(cwd2, ["rev-parse", "--abbrev-ref", "HEAD"]);
74488
+ function resolveGitBranch(cwd2, timeoutMs) {
74489
+ const branch = runGit(cwd2, ["rev-parse", "--abbrev-ref", "HEAD"], timeoutMs);
73605
74490
  return branch === "HEAD" ? "" : branch;
73606
74491
  }
74492
+ var GIT_RENDER_TIMEOUT_MS = GIT_STATUS_TIMEOUT_MS;
74493
+ function resolveGitBranchOrCommit(cwd2, timeoutMs) {
74494
+ const current = runGit(cwd2, ["branch", "--show-current"], timeoutMs);
74495
+ if (current)
74496
+ return current;
74497
+ return runGit(cwd2, ["rev-parse", "--short", "HEAD"], timeoutMs);
74498
+ }
73607
74499
 
73608
74500
  // src/domains/hooks/handlers/session-init/handler.ts
73609
74501
  var KNOWN_SOURCES = new Set(["startup", "resume", "clear", "compact"]);
@@ -73617,11 +74509,11 @@ function resolveEnvFilePath(settingsDir) {
73617
74509
  const override = process.env.CLAUDE_ENV_FILE;
73618
74510
  if (override && override.trim().length > 0)
73619
74511
  return override;
73620
- return join105(settingsDir, DEFAULT_ENV_FILE);
74512
+ return join107(settingsDir, DEFAULT_ENV_FILE);
73621
74513
  }
73622
74514
  function persistEntries(envFilePath, entries) {
73623
74515
  try {
73624
- mkdirSync5(dirname28(envFilePath), { recursive: true });
74516
+ mkdirSync6(dirname28(envFilePath), { recursive: true });
73625
74517
  writeEnvFile(envFilePath, entries);
73626
74518
  return true;
73627
74519
  } catch {
@@ -73672,9 +74564,9 @@ var sessionInit = {
73672
74564
  // src/domains/hooks/handlers/_shared/context-assembler.ts
73673
74565
  import { execFileSync as execFileSync3 } from "node:child_process";
73674
74566
  import { createHash as createHash15 } from "node:crypto";
73675
- import { existsSync as existsSync50, mkdirSync as mkdirSync6, readFileSync as readFileSync17, rmSync as rmSync3, statSync as statSync8, writeFileSync as writeFileSync9 } from "node:fs";
74567
+ import { existsSync as existsSync52, mkdirSync as mkdirSync7, readFileSync as readFileSync17, rmSync as rmSync5, statSync as statSync9, writeFileSync as writeFileSync10 } from "node:fs";
73676
74568
  import { homedir as homedir27, platform as platform9, tmpdir as tmpdir4 } from "node:os";
73677
- import { basename as basename18, join as join106, resolve as resolve21 } from "node:path";
74569
+ import { basename as basename18, join as join108, resolve as resolve21 } from "node:path";
73678
74570
  var INJECTED_TTL_MS = 12 * 60 * 60 * 1000;
73679
74571
  var RESERVATION_TTL_MS = 60 * 1000;
73680
74572
  function gitBranch(dir) {
@@ -73751,16 +74643,16 @@ function scopeKey(baseDir) {
73751
74643
  return `${slug}-${hash}`;
73752
74644
  }
73753
74645
  function stateDir() {
73754
- return join106(tmpdir4(), "takumi-context-throttle");
74646
+ return join108(tmpdir4(), "takumi-context-throttle");
73755
74647
  }
73756
74648
  function stateFile(sessionId, scope, transcriptPath) {
73757
74649
  const key = `${sessionId}\x00${scope}\x00${transcriptPath ?? ""}`;
73758
74650
  const hash = createHash15("sha256").update(key).digest("hex").slice(0, 32);
73759
- return join106(stateDir(), `${hash}.json`);
74651
+ return join108(stateDir(), `${hash}.json`);
73760
74652
  }
73761
74653
  function readState(file) {
73762
74654
  try {
73763
- if (!existsSync50(file))
74655
+ if (!existsSync52(file))
73764
74656
  return null;
73765
74657
  return JSON.parse(readFileSync17(file, "utf8"));
73766
74658
  } catch {
@@ -73768,14 +74660,14 @@ function readState(file) {
73768
74660
  }
73769
74661
  }
73770
74662
  function writeState(file, state) {
73771
- mkdirSync6(stateDir(), { recursive: true });
73772
- writeFileSync9(file, JSON.stringify(state), "utf8");
74663
+ mkdirSync7(stateDir(), { recursive: true });
74664
+ writeFileSync10(file, JSON.stringify(state), "utf8");
73773
74665
  }
73774
74666
  function transcriptSize(transcriptPath) {
73775
74667
  if (!transcriptPath)
73776
74668
  return 0;
73777
74669
  try {
73778
- return statSync8(transcriptPath).size;
74670
+ return statSync9(transcriptPath).size;
73779
74671
  } catch {
73780
74672
  return 0;
73781
74673
  }
@@ -73820,14 +74712,14 @@ function clearPending(sessionId, scope, transcriptPath) {
73820
74712
  if (state.injectedAt) {
73821
74713
  writeState(file, { ...state, pending: false, reservedAt: undefined });
73822
74714
  } else {
73823
- rmSync3(file, { force: true });
74715
+ rmSync5(file, { force: true });
73824
74716
  }
73825
74717
  } catch {}
73826
74718
  }
73827
74719
  function resolveSkillsVenv(_cwd) {
73828
- const base = join106(homedir27(), ".claude", "skills", ".venv");
73829
- const interpreter = platform9() === "win32" ? join106(base, "Scripts", "python.exe") : join106(base, "bin", "python3");
73830
- return existsSync50(interpreter) ? interpreter : null;
74720
+ const base = join108(homedir27(), ".claude", "skills", ".venv");
74721
+ const interpreter = platform9() === "win32" ? join108(base, "Scripts", "python.exe") : join108(base, "bin", "python3");
74722
+ return existsSync52(interpreter) ? interpreter : null;
73831
74723
  }
73832
74724
 
73833
74725
  // src/domains/hooks/handlers/session-prompt-context/handler.ts
@@ -73865,12 +74757,12 @@ var sessionPromptContext = {
73865
74757
  };
73866
74758
 
73867
74759
  // src/domains/hooks/handlers/session-subagent-init/context-block.ts
73868
- import { join as join108 } from "node:path";
74760
+ import { join as join110 } from "node:path";
73869
74761
 
73870
74762
  // src/domains/hooks/handlers/session-subagent-init/context-sources.ts
73871
74763
  import { execFileSync as execFileSync4 } from "node:child_process";
73872
- import { readdirSync as readdirSync8, statSync as statSync9 } from "node:fs";
73873
- import { isAbsolute as isAbsolute4, join as join107, resolve as resolve22 } from "node:path";
74764
+ import { readdirSync as readdirSync9, statSync as statSync10 } from "node:fs";
74765
+ import { isAbsolute as isAbsolute4, join as join109, resolve as resolve22 } from "node:path";
73874
74766
  var MAX_DOCS_FILES = 15;
73875
74767
  var MAX_DOCS_SUBDIRS = 5;
73876
74768
  function gitFacts(dir) {
@@ -73902,16 +74794,16 @@ function planDirTemplate(format, dateStr) {
73902
74794
  }
73903
74795
  function detectPlan(plansAbs) {
73904
74796
  try {
73905
- const entries = readdirSync8(plansAbs, { withFileTypes: true });
74797
+ const entries = readdirSync9(plansAbs, { withFileTypes: true });
73906
74798
  let best = null;
73907
74799
  for (const e2 of entries) {
73908
74800
  if (!e2.isDirectory())
73909
74801
  continue;
73910
- const dir = join107(plansAbs, e2.name);
74802
+ const dir = join109(plansAbs, e2.name);
73911
74803
  try {
73912
- if (!readdirSync8(dir).includes("plan.md"))
74804
+ if (!readdirSync9(dir).includes("plan.md"))
73913
74805
  continue;
73914
- const mtime = statSync9(join107(dir, "plan.md")).mtimeMs;
74806
+ const mtime = statSync10(join109(dir, "plan.md")).mtimeMs;
73915
74807
  if (!best || mtime > best.mtime)
73916
74808
  best = { name: e2.name, mtime };
73917
74809
  } catch {}
@@ -73923,7 +74815,7 @@ function detectPlan(plansAbs) {
73923
74815
  }
73924
74816
  function docsCatalogue(docsAbs) {
73925
74817
  try {
73926
- const entries = readdirSync8(docsAbs, { withFileTypes: true });
74818
+ const entries = readdirSync9(docsAbs, { withFileTypes: true });
73927
74819
  const files = entries.filter((e2) => e2.isFile() && e2.name.toLowerCase().endsWith(".md")).map((e2) => e2.name).sort();
73928
74820
  const subdirs = entries.filter((e2) => e2.isDirectory()).map((e2) => e2.name).sort();
73929
74821
  const lines = [];
@@ -73934,7 +74826,7 @@ function docsCatalogue(docsAbs) {
73934
74826
  for (const d3 of subdirs.slice(0, MAX_DOCS_SUBDIRS)) {
73935
74827
  let count = 0;
73936
74828
  try {
73937
- count = readdirSync8(join107(docsAbs, d3)).length;
74829
+ count = readdirSync9(join109(docsAbs, d3)).length;
73938
74830
  } catch {}
73939
74831
  lines.push(`- ${d3}/ (${count} entries)`);
73940
74832
  }
@@ -73978,11 +74870,11 @@ function buildSubagentContext(input, ctx) {
73978
74870
  const agentId = strField(input, "agent_id") || "unknown";
73979
74871
  const plansAbs = abs(base, cfg.paths?.plans?.trim() || "plans");
73980
74872
  const docsAbs = abs(base, cfg.paths?.docs?.trim() || "docs");
73981
- const reportsAbs = join108(plansAbs, cfg.plan?.reportsDir?.trim() || "reports");
74873
+ const reportsAbs = join110(plansAbs, cfg.plan?.reportsDir?.trim() || "reports");
73982
74874
  const dateStr = stamp(cfg.plan?.dateFormat?.trim() || "YYMMDD-HHmm", new Date);
73983
74875
  const namingFormat = cfg.plan?.namingFormat?.trim() || "{date}-{slug}";
73984
- const planDir = join108(plansAbs, planDirTemplate(namingFormat, dateStr));
73985
- const reportFile = join108(reportsAbs, `${agentKey}-${dateStr}-{slug}-report.md`);
74876
+ const planDir = join110(plansAbs, planDirTemplate(namingFormat, dateStr));
74877
+ const reportFile = join110(reportsAbs, `${agentKey}-${dateStr}-{slug}-report.md`);
73986
74878
  const activePlan = detectPlan(plansAbs);
73987
74879
  const venv = resolveSkillsVenv(effectiveCwd);
73988
74880
  const respLang = cfg.locale?.responseLanguage?.trim() || null;
@@ -74060,12 +74952,12 @@ var sessionSubagentInit = {
74060
74952
  // src/domains/hooks/handlers/session-wip-checkpoint/handler.ts
74061
74953
  import { execFileSync as execFileSync5 } from "node:child_process";
74062
74954
  var CONFIG_KEY5 = "precompact-guard";
74063
- var GIT_STATUS_TIMEOUT_MS = 800;
74955
+ var GIT_STATUS_TIMEOUT_MS2 = 800;
74064
74956
  function countUncommittedEntries(cwd2) {
74065
74957
  try {
74066
74958
  const stdout = execFileSync5("git", ["status", "--porcelain"], {
74067
74959
  cwd: cwd2,
74068
- timeout: GIT_STATUS_TIMEOUT_MS,
74960
+ timeout: GIT_STATUS_TIMEOUT_MS2,
74069
74961
  encoding: "utf8",
74070
74962
  stdio: ["ignore", "pipe", "ignore"],
74071
74963
  windowsHide: true
@@ -74102,6 +74994,69 @@ var sessionWipCheckpoint = {
74102
74994
  }
74103
74995
  };
74104
74996
 
74997
+ // src/domains/hooks/handlers/usage-cache/handler.ts
74998
+ import { spawn as spawn4 } from "node:child_process";
74999
+ init_usage_credential();
75000
+ init_usage_limits_cache();
75001
+ var ENABLE_GATE_KEY2 = "usage-context-awareness";
75002
+ var REFRESH_INTERVAL_PROMPT_MS = 60000;
75003
+ var REFRESH_INTERVAL_TOOL_MS = 300000;
75004
+ var RECORD_RESULT2 = { status: "record", timingMs: 0 };
75005
+ var NOOP_RESULT2 = { status: "no-op", timingMs: 0 };
75006
+ function isPromptEvent(event) {
75007
+ return event === "SessionStart" || event === "UserPromptSubmit";
75008
+ }
75009
+ function decideUsageRefresh(ctx, event) {
75010
+ if (!isHandlerEnabled(ctx, ENABLE_GATE_KEY2))
75011
+ return "disabled";
75012
+ if (hasAnthropicRuntimeOverride())
75013
+ return "override";
75014
+ const interval = isPromptEvent(event) ? REFRESH_INTERVAL_PROMPT_MS : REFRESH_INTERVAL_TOOL_MS;
75015
+ return getCacheAgeMs(readUsageCache()) >= interval ? "refresh" : "throttled";
75016
+ }
75017
+ function spawnRefresh(ctx) {
75018
+ try {
75019
+ const { command, prefixArgs } = resolveInvocationPrefix();
75020
+ const args = [...prefixArgs, "statusline", "--refresh-usage-cache"];
75021
+ if (ctx.runtimeFlags?.debug)
75022
+ args.push("--debug");
75023
+ const child = spawn4(command, args, {
75024
+ detached: true,
75025
+ stdio: "ignore",
75026
+ env: buildChildEnv()
75027
+ });
75028
+ child.on("error", (err) => {
75029
+ hookLog("usage_cache_refresh", { spawn_error: err.message });
75030
+ });
75031
+ child.unref();
75032
+ } catch (err) {
75033
+ hookLog("usage_cache_refresh", {
75034
+ spawn_error: err instanceof Error ? err.message : String(err)
75035
+ });
75036
+ }
75037
+ }
75038
+ var usageCache = {
75039
+ name: "perf-usage-cache",
75040
+ category: "perf",
75041
+ policy: "record",
75042
+ events: ["SessionStart", "UserPromptSubmit", "PostToolUse"],
75043
+ installAgents: ["claude"],
75044
+ run(_input, ctx) {
75045
+ try {
75046
+ if (ctx.agent !== "claude")
75047
+ return NOOP_RESULT2;
75048
+ const decision = decideUsageRefresh(ctx, ctx.event);
75049
+ if (decision === "disabled")
75050
+ return NOOP_RESULT2;
75051
+ if (decision === "refresh")
75052
+ spawnRefresh(ctx);
75053
+ return RECORD_RESULT2;
75054
+ } catch {
75055
+ return NOOP_RESULT2;
75056
+ }
75057
+ }
75058
+ };
75059
+
74105
75060
  // src/domains/hooks/handlers/registry.ts
74106
75061
  var HOOK_HANDLERS = [
74107
75062
  guardJailbreak,
@@ -74115,7 +75070,9 @@ var HOOK_HANDLERS = [
74115
75070
  conventionQualityGate,
74116
75071
  extensionSkill,
74117
75072
  metricsRecord,
74118
- metricsFlush
75073
+ metricsFlush,
75074
+ usageCache,
75075
+ sessionActivity
74119
75076
  ];
74120
75077
  function shortHandlerName(handler) {
74121
75078
  const prefix = `${handler.category}-`;
@@ -74588,7 +75545,7 @@ init_hooks_settings_merger();
74588
75545
 
74589
75546
  // src/commands/portable/settings-write-with-confirm.ts
74590
75547
  init_safe_prompts();
74591
- import { existsSync as existsSync51, mkdirSync as mkdirSync7, readFileSync as readFileSync18, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "node:fs";
75548
+ import { existsSync as existsSync53, mkdirSync as mkdirSync8, readFileSync as readFileSync19, renameSync as renameSync4, rmSync as rmSync6, writeFileSync as writeFileSync11 } from "node:fs";
74592
75549
  import { dirname as dirname29 } from "node:path";
74593
75550
 
74594
75551
  // node_modules/diff/libesm/diff/base.js
@@ -75761,11 +76718,11 @@ var EMPTY_RESULT = (status2) => ({
75761
76718
  backupPath: null
75762
76719
  });
75763
76720
  function readCurrent(path10) {
75764
- if (!existsSync51(path10))
76721
+ if (!existsSync53(path10))
75765
76722
  return { kind: "missing" };
75766
76723
  let raw = "";
75767
76724
  try {
75768
- raw = readFileSync18(path10, "utf8");
76725
+ raw = readFileSync19(path10, "utf8");
75769
76726
  const parsed = JSON.parse(raw);
75770
76727
  return { kind: "ok", raw, parsed };
75771
76728
  } catch {
@@ -75792,13 +76749,13 @@ function diffStats(diff) {
75792
76749
  return { additions, deletions };
75793
76750
  }
75794
76751
  function atomicWrite2(path10, contents, backupPath) {
75795
- mkdirSync7(dirname29(path10), { recursive: true });
76752
+ mkdirSync8(dirname29(path10), { recursive: true });
75796
76753
  const tmp = `${path10}.tmp`;
75797
76754
  try {
75798
- writeFileSync10(tmp, contents);
75799
- renameSync3(tmp, path10);
76755
+ writeFileSync11(tmp, contents);
76756
+ renameSync4(tmp, path10);
75800
76757
  } catch (err) {
75801
- rmSync4(tmp, { force: true });
76758
+ rmSync6(tmp, { force: true });
75802
76759
  const trailer = backupPath ? `. Backup preserved at: ${backupPath}` : "";
75803
76760
  throw new Error(`Failed to write ${path10}: ${err instanceof Error ? err.message : String(err)}${trailer}`);
75804
76761
  }
@@ -75807,7 +76764,7 @@ function writeBackup(path10, raw) {
75807
76764
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
75808
76765
  const backupPath = `${path10}.${timestamp}.bak`;
75809
76766
  try {
75810
- writeFileSync10(backupPath, raw);
76767
+ writeFileSync11(backupPath, raw);
75811
76768
  return backupPath;
75812
76769
  } catch {
75813
76770
  return null;
@@ -75878,18 +76835,18 @@ init_dist2();
75878
76835
  // src/commands/hooks/lib/agent-target-picker.ts
75879
76836
  init_safe_prompts();
75880
76837
  init_dist2();
75881
- import { existsSync as existsSync52 } from "node:fs";
76838
+ import { existsSync as existsSync54 } from "node:fs";
75882
76839
 
75883
76840
  // src/commands/hooks/lib/settings-path-resolver.ts
75884
76841
  import { lstatSync as lstatSync3, realpathSync as realpathSync3 } from "node:fs";
75885
- import { homedir as homedir28 } from "node:os";
75886
- import { join as join109 } from "node:path";
76842
+ import { homedir as homedir29 } from "node:os";
76843
+ import { join as join112 } from "node:path";
75887
76844
  function rawPath(agent, global3) {
75888
- const root = global3 ? homedir28() : process.cwd();
76845
+ const root = global3 ? homedir29() : process.cwd();
75889
76846
  if (agent === "claude") {
75890
- return join109(root, ".claude", "settings.json");
76847
+ return join112(root, ".claude", "settings.json");
75891
76848
  }
75892
- return join109(root, ".codex", "hooks.json");
76849
+ return join112(root, ".codex", "hooks.json");
75893
76850
  }
75894
76851
  function resolveSettingsPath(agent, options2 = {}) {
75895
76852
  const originalPath = rawPath(agent, Boolean(options2.global));
@@ -75917,7 +76874,7 @@ function probe(global3) {
75917
76874
  return {
75918
76875
  agent,
75919
76876
  path: location2.realPath,
75920
- exists: existsSync52(location2.realPath)
76877
+ exists: existsSync54(location2.realPath)
75921
76878
  };
75922
76879
  });
75923
76880
  }
@@ -76020,6 +76977,8 @@ function planEntry(handler, event, agent, bin, flags) {
76020
76977
  function buildHookSection(agent, bin, flags = {}, handlers3 = HOOK_HANDLERS) {
76021
76978
  const section = {};
76022
76979
  for (const handler of handlers3) {
76980
+ if (handler.installAgents && !handler.installAgents.includes(agent))
76981
+ continue;
76023
76982
  for (const event of handler.events) {
76024
76983
  const planned = planEntry(handler, event, agent, bin, flags);
76025
76984
  if (!planned)
@@ -76038,9 +76997,82 @@ function buildHookSection(agent, bin, flags = {}, handlers3 = HOOK_HANDLERS) {
76038
76997
  return section;
76039
76998
  }
76040
76999
 
77000
+ // src/commands/hooks/lib/install-statusline.ts
77001
+ var USAGE_HANDLER = "perf-usage-cache";
77002
+ var ACTIVITY_HANDLER = "session-activity";
77003
+ var USAGE_PRODUCERS = ["usage-quota-cache-refresh.cjs", "usage-context-awareness.cjs"];
77004
+ var ACTIVITY_PRODUCER = "session-state.cjs";
77005
+ var ACTIVITY_PRODUCER_EVENT = "PostToolUse";
77006
+ function buildStatuslineCommand(bin, flags) {
77007
+ const parts = [bin || DEFAULT_HOOK_BIN, "statusline"];
77008
+ if (flags.debug)
77009
+ parts.push("--debug");
77010
+ return parts.join(" ");
77011
+ }
77012
+ function strippedBasenamesForEvent(event, installsUsage, installsActivity) {
77013
+ const out = [];
77014
+ if (installsUsage)
77015
+ out.push(...USAGE_PRODUCERS);
77016
+ if (installsActivity && event === ACTIVITY_PRODUCER_EVENT)
77017
+ out.push(ACTIVITY_PRODUCER);
77018
+ return out;
77019
+ }
77020
+ function commandReferences(command, basename19) {
77021
+ return typeof command === "string" && command.includes(basename19);
77022
+ }
77023
+ function isCliStatuslineCommand(command) {
77024
+ return /^\S+\s+statusline(\s|$)/.test(command);
77025
+ }
77026
+ function shouldSetStatusline(command) {
77027
+ if (typeof command !== "string" || command.trim() === "")
77028
+ return true;
77029
+ return command.includes("statusline.cjs") || isCliStatuslineCommand(command);
77030
+ }
77031
+ function installStatusline(settings, opts) {
77032
+ if (opts.agent !== "claude")
77033
+ return settings;
77034
+ const installsUsage = opts.handlerNames.has(USAGE_HANDLER);
77035
+ const installsActivity = opts.handlerNames.has(ACTIVITY_HANDLER);
77036
+ if (!installsUsage && !installsActivity)
77037
+ return settings;
77038
+ const next = { ...settings };
77039
+ if (installsUsage && installsActivity) {
77040
+ const existing = next.statusLine;
77041
+ if (shouldSetStatusline(existing?.command)) {
77042
+ const command = buildStatuslineCommand(opts.bin, opts.flags ?? {});
77043
+ next.statusLine = { type: "command", ...existing ?? {}, command };
77044
+ }
77045
+ }
77046
+ const hooks = next.hooks;
77047
+ if (hooks && typeof hooks === "object") {
77048
+ const rebuilt = {};
77049
+ for (const [event, groups] of Object.entries(hooks)) {
77050
+ if (!Array.isArray(groups)) {
77051
+ rebuilt[event] = groups;
77052
+ continue;
77053
+ }
77054
+ const strip = strippedBasenamesForEvent(event, installsUsage, installsActivity);
77055
+ const keptGroups = [];
77056
+ for (const group of groups) {
77057
+ if (!Array.isArray(group.hooks)) {
77058
+ keptGroups.push(group);
77059
+ continue;
77060
+ }
77061
+ const keptHooks = group.hooks.filter((entry) => !strip.some((basename19) => commandReferences(entry.command, basename19)));
77062
+ if (keptHooks.length > 0)
77063
+ keptGroups.push({ ...group, hooks: keptHooks });
77064
+ }
77065
+ if (keptGroups.length > 0)
77066
+ rebuilt[event] = keptGroups;
77067
+ }
77068
+ next.hooks = rebuilt;
77069
+ }
77070
+ return next;
77071
+ }
77072
+
76041
77073
  // src/commands/hooks/uninstall-handler.ts
76042
77074
  init_logger();
76043
- import { existsSync as existsSync53, mkdirSync as mkdirSync8, readFileSync as readFileSync19, renameSync as renameSync4, rmSync as rmSync5, writeFileSync as writeFileSync11 } from "node:fs";
77075
+ import { existsSync as existsSync55, mkdirSync as mkdirSync9, readFileSync as readFileSync20, renameSync as renameSync5, rmSync as rmSync7, writeFileSync as writeFileSync12 } from "node:fs";
76044
77076
  import { dirname as dirname30 } from "node:path";
76045
77077
  var AGENT_DISPLAY2 = {
76046
77078
  claude: "Claude Code",
@@ -76082,13 +77114,13 @@ function pruneHooksSection(hooks, agent) {
76082
77114
  return { pruned, removed };
76083
77115
  }
76084
77116
  function writeAtomic(path10, contents) {
76085
- mkdirSync8(dirname30(path10), { recursive: true });
77117
+ mkdirSync9(dirname30(path10), { recursive: true });
76086
77118
  const tmp = `${path10}.tmp`;
76087
77119
  try {
76088
- writeFileSync11(tmp, contents);
76089
- renameSync4(tmp, path10);
77120
+ writeFileSync12(tmp, contents);
77121
+ renameSync5(tmp, path10);
76090
77122
  } catch (err) {
76091
- rmSync5(tmp, { force: true });
77123
+ rmSync7(tmp, { force: true });
76092
77124
  throw err;
76093
77125
  }
76094
77126
  }
@@ -76100,12 +77132,12 @@ async function uninstallForAgent(agent, options2) {
76100
77132
  removed: 0,
76101
77133
  dryRun: Boolean(options2.dryRun)
76102
77134
  };
76103
- if (!existsSync53(location2.realPath)) {
77135
+ if (!existsSync55(location2.realPath)) {
76104
77136
  return result;
76105
77137
  }
76106
77138
  let parsed;
76107
77139
  try {
76108
- parsed = JSON.parse(readFileSync19(location2.realPath, "utf8"));
77140
+ parsed = JSON.parse(readFileSync20(location2.realPath, "utf8"));
76109
77141
  } catch {
76110
77142
  logger.warning(`[hooks] could not parse ${location2.realPath}; uninstall skipped to avoid clobbering`);
76111
77143
  return result;
@@ -76169,11 +77201,13 @@ function eventsSummary(section) {
76169
77201
  }
76170
77202
  async function installForAgent(agent, options2, interactive, useStepUI) {
76171
77203
  const location2 = resolveSettingsPath(agent, { global: options2.global });
77204
+ const handlers3 = selectHandlersForInstall(options2.categories);
76172
77205
  const section = buildHookSection(agent, options2.bin, {
76173
77206
  noDetach: options2.noDetach,
76174
77207
  debug: options2.debug
76175
- }, selectHandlersForInstall(options2.categories));
77208
+ }, handlers3);
76176
77209
  const entriesPlanned = countEntries(section);
77210
+ const handlerNames = new Set(handlers3.map((h2) => h2.name));
76177
77211
  const result = await writeSettingsWithConfirm({
76178
77212
  path: location2.realPath,
76179
77213
  label: `${AGENT_DISPLAY3[agent]} settings`,
@@ -76182,7 +77216,13 @@ async function installForAgent(agent, options2, interactive, useStepUI) {
76182
77216
  const existingHooks = safeCurrent.hooks ?? {};
76183
77217
  const { pruned } = pruneHooksSection(existingHooks, agent);
76184
77218
  const purged = { ...safeCurrent, hooks: pruned };
76185
- return mergeHooksObject(purged, section);
77219
+ const merged = mergeHooksObject(purged, section);
77220
+ return installStatusline(merged, {
77221
+ agent,
77222
+ handlerNames,
77223
+ bin: options2.bin,
77224
+ flags: { noDetach: options2.noDetach, debug: options2.debug }
77225
+ });
76186
77226
  },
76187
77227
  missingFile: resolveMissingFileMode(options2, interactive),
76188
77228
  yes: options2.yes,
@@ -76319,7 +77359,7 @@ async function installHook(options2) {
76319
77359
  // src/commands/hooks/status.ts
76320
77360
  init_takumi_config_manager();
76321
77361
  init_logger();
76322
- import { existsSync as existsSync54, readFileSync as readFileSync20 } from "node:fs";
77362
+ import { existsSync as existsSync56, readFileSync as readFileSync21 } from "node:fs";
76323
77363
  var AGENT_DISPLAY4 = { claude: "Claude Code", codex: "Codex" };
76324
77364
  var NEW_SHAPE = /\bhook-exec\b.*--hook\s+(guard|session|convention|extension|metrics|perf)\.(\S+).*-a\s+(claude|codex)(?![\w-])/;
76325
77365
  var LEGACY_SHAPE = /\bhooks\s+(?:session-start|user-prompt-submit|pre-tool-use|post-tool-use|stop|session-end)\s+-a\s+(claude|codex)(?![\w-])/;
@@ -76349,7 +77389,7 @@ async function statusForAgent(agent, options2, cwd2 = process.cwd()) {
76349
77389
  const result = {
76350
77390
  agent,
76351
77391
  settingsPath: location2.realPath,
76352
- exists: existsSync54(location2.realPath),
77392
+ exists: existsSync56(location2.realPath),
76353
77393
  shape: "none",
76354
77394
  byCategory: {},
76355
77395
  newEntryCount: 0,
@@ -76360,7 +77400,7 @@ async function statusForAgent(agent, options2, cwd2 = process.cwd()) {
76360
77400
  return result;
76361
77401
  let hooks;
76362
77402
  try {
76363
- const parsed = JSON.parse(readFileSync20(location2.realPath, "utf8"));
77403
+ const parsed = JSON.parse(readFileSync21(location2.realPath, "utf8"));
76364
77404
  hooks = parsed.hooks ?? {};
76365
77405
  } catch {
76366
77406
  return result;
@@ -77350,7 +78390,7 @@ async function promptFreshConfirmation(targetPath, analysis) {
77350
78390
  // src/domains/ui/prompts/confirmation-prompts.ts
77351
78391
  init_output_manager();
77352
78392
  init_safe_prompts();
77353
- import { platform as platform10 } from "node:os";
78393
+ import { platform as platform11 } from "node:os";
77354
78394
 
77355
78395
  // src/types/skills-dependencies.ts
77356
78396
  var SKILLS_DEPENDENCIES = {
@@ -77412,7 +78452,7 @@ async function promptSkillsInstallation() {
77412
78452
  if (output.isJson()) {
77413
78453
  return false;
77414
78454
  }
77415
- const isWindows2 = platform10() === "win32";
78455
+ const isWindows2 = platform11() === "win32";
77416
78456
  const pythonDeps = formatDependencyList(SKILLS_DEPENDENCIES.python);
77417
78457
  const systemDeps = formatDependencyList(SKILLS_DEPENDENCIES.system);
77418
78458
  const nodeDeps = formatDependencyList(SKILLS_DEPENDENCIES.node);
@@ -77590,7 +78630,7 @@ init_logger();
77590
78630
  init_takumi_constants();
77591
78631
  var import_fs_extra33 = __toESM(require_lib(), 1);
77592
78632
  var import_semver5 = __toESM(require_semver2(), 1);
77593
- import { join as join110 } from "node:path";
78633
+ import { join as join113 } from "node:path";
77594
78634
  function evaluateCliVersionGate(input) {
77595
78635
  const min = typeof input.minCliVersion === "string" ? input.minCliVersion.trim() : undefined;
77596
78636
  if (!min)
@@ -77611,7 +78651,7 @@ function evaluateCliVersionGate(input) {
77611
78651
  }
77612
78652
  async function readKitMinCliVersion(extractDir) {
77613
78653
  try {
77614
- const resolved = await findManifestPath(join110(extractDir, ".claude"));
78654
+ const resolved = await findManifestPath(join113(extractDir, ".claude"));
77615
78655
  if (!resolved)
77616
78656
  return;
77617
78657
  const raw = await import_fs_extra33.readFile(resolved.path, "utf-8");
@@ -77803,7 +78843,7 @@ init_logger();
77803
78843
  init_safe_spinner();
77804
78844
  import { mkdir as mkdir25, stat as stat11 } from "node:fs/promises";
77805
78845
  import { tmpdir as tmpdir5 } from "node:os";
77806
- import { join as join116 } from "node:path";
78846
+ import { join as join119 } from "node:path";
77807
78847
 
77808
78848
  // src/shared/temp-cleanup.ts
77809
78849
  init_logger();
@@ -77820,9 +78860,9 @@ var import_ignore6 = __toESM(require_ignore(), 1);
77820
78860
  // src/domains/installation/download/file-downloader.ts
77821
78861
  init_logger();
77822
78862
  init_output_manager();
77823
- import { createWriteStream as createWriteStream2, rmSync as rmSync6 } from "node:fs";
78863
+ import { createWriteStream as createWriteStream2, rmSync as rmSync8 } from "node:fs";
77824
78864
  import { mkdir as mkdir21 } from "node:fs/promises";
77825
- import { join as join111 } from "node:path";
78865
+ import { join as join114 } from "node:path";
77826
78866
 
77827
78867
  // src/shared/progress-bar.ts
77828
78868
  init_output_manager();
@@ -78032,7 +79072,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
78032
79072
  class FileDownloader {
78033
79073
  async downloadAsset(asset, destDir) {
78034
79074
  try {
78035
- const destPath = join111(destDir, asset.name);
79075
+ const destPath = join114(destDir, asset.name);
78036
79076
  await mkdir21(destDir, { recursive: true });
78037
79077
  output.info(`Downloading ${asset.name} (${formatBytes(asset.size)})...`);
78038
79078
  logger.verbose("Download details", {
@@ -78090,7 +79130,7 @@ class FileDownloader {
78090
79130
  fileStream.end();
78091
79131
  await new Promise((resolve24) => fileStream.once("close", resolve24));
78092
79132
  try {
78093
- rmSync6(destPath, { force: true });
79133
+ rmSync8(destPath, { force: true });
78094
79134
  } catch (cleanupError) {
78095
79135
  const errorMsg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
78096
79136
  logger.debug(`Failed to clean up partial download ${destPath}: ${errorMsg}`);
@@ -78104,7 +79144,7 @@ class FileDownloader {
78104
79144
  fileStream.end();
78105
79145
  await new Promise((resolve24) => fileStream.once("close", resolve24));
78106
79146
  try {
78107
- rmSync6(destPath, { force: true });
79147
+ rmSync8(destPath, { force: true });
78108
79148
  } catch (cleanupError) {
78109
79149
  const errorMsg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
78110
79150
  logger.debug(`Failed to clean up partial download ${destPath}: ${errorMsg}`);
@@ -78117,7 +79157,7 @@ class FileDownloader {
78117
79157
  }
78118
79158
  async downloadFile(params) {
78119
79159
  const { url, name: name2, size, destDir, token } = params;
78120
- const destPath = join111(destDir, name2);
79160
+ const destPath = join114(destDir, name2);
78121
79161
  await mkdir21(destDir, { recursive: true });
78122
79162
  output.info(`Downloading ${name2}${size ? ` (${formatBytes(size)})` : ""}...`);
78123
79163
  const headers = {};
@@ -78187,7 +79227,7 @@ class FileDownloader {
78187
79227
  fileStream.end();
78188
79228
  await new Promise((resolve24) => fileStream.once("close", resolve24));
78189
79229
  try {
78190
- rmSync6(destPath, { force: true });
79230
+ rmSync8(destPath, { force: true });
78191
79231
  } catch (cleanupError) {
78192
79232
  const errorMsg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
78193
79233
  logger.debug(`Failed to clean up partial download ${destPath}: ${errorMsg}`);
@@ -78205,7 +79245,7 @@ class FileDownloader {
78205
79245
  fileStream.end();
78206
79246
  await new Promise((resolve24) => fileStream.once("close", resolve24));
78207
79247
  try {
78208
- rmSync6(destPath, { force: true });
79248
+ rmSync8(destPath, { force: true });
78209
79249
  } catch (cleanupError) {
78210
79250
  const errorMsg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
78211
79251
  logger.debug(`Failed to clean up partial download ${destPath}: ${errorMsg}`);
@@ -78220,7 +79260,7 @@ init_logger();
78220
79260
  init_types2();
78221
79261
  import { constants as constants3 } from "node:fs";
78222
79262
  import { access as access3, readdir as readdir26 } from "node:fs/promises";
78223
- import { join as join112 } from "node:path";
79263
+ import { join as join115 } from "node:path";
78224
79264
  async function validateExtraction(extractDir) {
78225
79265
  try {
78226
79266
  const entries = await readdir26(extractDir, { encoding: "utf8" });
@@ -78232,7 +79272,7 @@ async function validateExtraction(extractDir) {
78232
79272
  const missingPaths = [];
78233
79273
  for (const path10 of criticalPaths) {
78234
79274
  try {
78235
- await access3(join112(extractDir, path10), constants3.F_OK);
79275
+ await access3(join115(extractDir, path10), constants3.F_OK);
78236
79276
  logger.debug(`Found: ${path10}`);
78237
79277
  } catch {
78238
79278
  logger.warning(`Expected path not found: ${path10}`);
@@ -78254,7 +79294,7 @@ async function validateExtraction(extractDir) {
78254
79294
  // src/domains/installation/extraction/tar-extractor.ts
78255
79295
  init_logger();
78256
79296
  import { copyFile as copyFile5, mkdir as mkdir23, readdir as readdir28, rm as rm8, stat as stat9 } from "node:fs/promises";
78257
- import { join as join114 } from "node:path";
79297
+ import { join as join117 } from "node:path";
78258
79298
 
78259
79299
  // node_modules/tar/dist/esm/index.min.js
78260
79300
  import Kr from "events";
@@ -81467,7 +82507,7 @@ function decodeFilePath(path10) {
81467
82507
  init_logger();
81468
82508
  init_types2();
81469
82509
  import { copyFile as copyFile4, lstat as lstat8, mkdir as mkdir22, readdir as readdir27 } from "node:fs/promises";
81470
- import { join as join113, relative as relative17 } from "node:path";
82510
+ import { join as join116, relative as relative17 } from "node:path";
81471
82511
  async function withRetry2(fn2, retries = 3) {
81472
82512
  for (let i = 0;i < retries; i++) {
81473
82513
  try {
@@ -81489,8 +82529,8 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
81489
82529
  await mkdir22(destDir, { recursive: true });
81490
82530
  const entries = await readdir27(sourceDir, { encoding: "utf8" });
81491
82531
  for (const entry of entries) {
81492
- const sourcePath = join113(sourceDir, entry);
81493
- const destPath = join113(destDir, entry);
82532
+ const sourcePath = join116(sourceDir, entry);
82533
+ const destPath = join116(destDir, entry);
81494
82534
  const relativePath = relative17(sourceDir, sourcePath);
81495
82535
  if (!isPathSafe(destDir, destPath)) {
81496
82536
  logger.warning(`Skipping unsafe path: ${relativePath}`);
@@ -81517,8 +82557,8 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
81517
82557
  await mkdir22(destDir, { recursive: true });
81518
82558
  const entries = await readdir27(sourceDir, { encoding: "utf8" });
81519
82559
  for (const entry of entries) {
81520
- const sourcePath = join113(sourceDir, entry);
81521
- const destPath = join113(destDir, entry);
82560
+ const sourcePath = join116(sourceDir, entry);
82561
+ const destPath = join116(destDir, entry);
81522
82562
  const relativePath = relative17(sourceDir, sourcePath);
81523
82563
  if (!isPathSafe(destDir, destPath)) {
81524
82564
  logger.warning(`Skipping unsafe path: ${relativePath}`);
@@ -81573,7 +82613,7 @@ class TarExtractor {
81573
82613
  logger.debug(`Root entries: ${entries.join(", ")}`);
81574
82614
  if (entries.length === 1) {
81575
82615
  const rootEntry = entries[0];
81576
- const rootPath = join114(tempExtractDir, rootEntry);
82616
+ const rootPath = join117(tempExtractDir, rootEntry);
81577
82617
  const rootStat = await stat9(rootPath);
81578
82618
  if (rootStat.isDirectory()) {
81579
82619
  const rootContents = await readdir28(rootPath, { encoding: "utf8" });
@@ -81589,7 +82629,7 @@ class TarExtractor {
81589
82629
  }
81590
82630
  } else {
81591
82631
  await mkdir23(destDir, { recursive: true });
81592
- await copyFile5(rootPath, join114(destDir, rootEntry));
82632
+ await copyFile5(rootPath, join117(destDir, rootEntry));
81593
82633
  }
81594
82634
  } else {
81595
82635
  logger.debug("Multiple root entries - moving all");
@@ -81610,7 +82650,7 @@ class TarExtractor {
81610
82650
  init_logger();
81611
82651
  import { createWriteStream as createWriteStream3 } from "node:fs";
81612
82652
  import { chmod as chmod4, copyFile as copyFile6, mkdir as mkdir24, readdir as readdir29, rm as rm9, stat as stat10 } from "node:fs/promises";
81613
- import { dirname as dirname31, join as join115, resolve as resolve24 } from "node:path";
82653
+ import { dirname as dirname31, join as join118, resolve as resolve24 } from "node:path";
81614
82654
  import { pipeline } from "node:stream/promises";
81615
82655
  import yauzl from "yauzl-promise";
81616
82656
  class ZipExtractor {
@@ -81624,7 +82664,7 @@ class ZipExtractor {
81624
82664
  logger.debug(`Root entries: ${entries.join(", ")}`);
81625
82665
  if (entries.length === 1) {
81626
82666
  const rootEntry = entries[0];
81627
- const rootPath = join115(tempExtractDir, rootEntry);
82667
+ const rootPath = join118(tempExtractDir, rootEntry);
81628
82668
  const rootStat = await stat10(rootPath);
81629
82669
  if (rootStat.isDirectory()) {
81630
82670
  const rootContents = await readdir29(rootPath, { encoding: "utf8" });
@@ -81640,7 +82680,7 @@ class ZipExtractor {
81640
82680
  }
81641
82681
  } else {
81642
82682
  await mkdir24(destDir, { recursive: true });
81643
- await copyFile6(rootPath, join115(destDir, rootEntry));
82683
+ await copyFile6(rootPath, join118(destDir, rootEntry));
81644
82684
  }
81645
82685
  } else {
81646
82686
  logger.debug("Multiple root entries - moving all");
@@ -81769,7 +82809,7 @@ class DownloadManager {
81769
82809
  async createTempDir() {
81770
82810
  const timestamp = Date.now();
81771
82811
  const counter = DownloadManager.tempDirCounter++;
81772
- const primaryTempDir = join116(tmpdir5(), `takumi-${timestamp}-${counter}`);
82812
+ const primaryTempDir = join119(tmpdir5(), `takumi-${timestamp}-${counter}`);
81773
82813
  try {
81774
82814
  await mkdir25(primaryTempDir, { recursive: true });
81775
82815
  logger.debug(`Created temp directory: ${primaryTempDir}`);
@@ -81786,7 +82826,7 @@ Solutions:
81786
82826
  2. Set HOME environment variable
81787
82827
  3. Try running from a different directory`);
81788
82828
  }
81789
- const fallbackTempDir = join116(homeDir, ".sunagentkit", "tmp", `takumi-${timestamp}-${counter}`);
82829
+ const fallbackTempDir = join119(homeDir, ".sunagentkit", "tmp", `takumi-${timestamp}-${counter}`);
81790
82830
  try {
81791
82831
  await mkdir25(fallbackTempDir, { recursive: true });
81792
82832
  logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
@@ -82493,7 +83533,7 @@ Re-run with explicit base kit, e.g. --kit ${BASE_KIT} --kit ${parsed2.join(" --k
82493
83533
  }
82494
83534
  // src/commands/init/phases/selection-handler.ts
82495
83535
  import { mkdir as mkdir26 } from "node:fs/promises";
82496
- import { join as join120, resolve as resolve28 } from "node:path";
83536
+ import { join as join123, resolve as resolve28 } from "node:path";
82497
83537
 
82498
83538
  // src/commands/shared/agent-selector.ts
82499
83539
  init_registry();
@@ -82646,8 +83686,8 @@ init_logger();
82646
83686
  init_safe_spinner();
82647
83687
  init_takumi_constants();
82648
83688
  var import_fs_extra34 = __toESM(require_lib(), 1);
82649
- import { existsSync as existsSync57, readdirSync as readdirSync9, rmSync as rmSync7, rmdirSync as rmdirSync2, unlinkSync as unlinkSync6 } from "node:fs";
82650
- import { dirname as dirname34, join as join119, resolve as resolve27 } from "node:path";
83689
+ import { existsSync as existsSync59, readdirSync as readdirSync10, rmSync as rmSync9, rmdirSync as rmdirSync2, unlinkSync as unlinkSync6 } from "node:fs";
83690
+ import { dirname as dirname34, join as join122, resolve as resolve27 } from "node:path";
82651
83691
  var TAKUMI_SUBDIRECTORIES = ["commands", "agents", "skills", "rules", "hooks"];
82652
83692
  async function analyzeFreshInstallation(claudeDir) {
82653
83693
  const metadata = await readManifest(claudeDir);
@@ -82696,7 +83736,7 @@ function cleanupEmptyDirectories2(filePath, claudeDir) {
82696
83736
  let currentDir = resolve27(dirname34(filePath));
82697
83737
  while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
82698
83738
  try {
82699
- const entries = readdirSync9(currentDir);
83739
+ const entries = readdirSync10(currentDir);
82700
83740
  if (entries.length === 0) {
82701
83741
  rmdirSync2(currentDir);
82702
83742
  logger.debug(`Removed empty directory: ${currentDir}`);
@@ -82717,9 +83757,9 @@ async function removeFilesByOwnership(claudeDir, analysis, includeModified) {
82717
83757
  const filesToRemove = includeModified ? [...analysis.ckFiles, ...analysis.ckModifiedFiles] : analysis.ckFiles;
82718
83758
  const filesToPreserve = includeModified ? analysis.userFiles : [...analysis.ckModifiedFiles, ...analysis.userFiles];
82719
83759
  for (const file of filesToRemove) {
82720
- const fullPath = join119(claudeDir, file.path);
83760
+ const fullPath = join122(claudeDir, file.path);
82721
83761
  try {
82722
- if (existsSync57(fullPath)) {
83762
+ if (existsSync59(fullPath)) {
82723
83763
  unlinkSync6(fullPath);
82724
83764
  removedFiles.push(file.path);
82725
83765
  logger.debug(`Removed: ${file.path}`);
@@ -82791,9 +83831,9 @@ async function removeSubdirectoriesFallback(claudeDir) {
82791
83831
  const removedFiles = [];
82792
83832
  let removedDirCount = 0;
82793
83833
  for (const subdir of TAKUMI_SUBDIRECTORIES) {
82794
- const subdirPath = join119(claudeDir, subdir);
83834
+ const subdirPath = join122(claudeDir, subdir);
82795
83835
  if (await import_fs_extra34.pathExists(subdirPath)) {
82796
- rmSync7(subdirPath, { recursive: true, force: true });
83836
+ rmSync9(subdirPath, { recursive: true, force: true });
82797
83837
  removedDirCount++;
82798
83838
  removedFiles.push(`${subdir}/ (entire directory)`);
82799
83839
  logger.debug(`Removed subdirectory: ${subdir}/`);
@@ -83016,7 +84056,7 @@ async function handleSelection(ctx) {
83016
84056
  }
83017
84057
  if (!ctx.options.fresh) {
83018
84058
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
83019
- const claudeDir = prefix ? join120(resolvedDir, prefix) : resolvedDir;
84059
+ const claudeDir = prefix ? join123(resolvedDir, prefix) : resolvedDir;
83020
84060
  try {
83021
84061
  const existingMetadata = await readManifest(claudeDir);
83022
84062
  if (existingMetadata?.kits) {
@@ -83049,7 +84089,7 @@ async function handleSelection(ctx) {
83049
84089
  }
83050
84090
  if (ctx.options.fresh) {
83051
84091
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
83052
- const claudeDir = prefix ? join120(resolvedDir, prefix) : resolvedDir;
84092
+ const claudeDir = prefix ? join123(resolvedDir, prefix) : resolvedDir;
83053
84093
  const canProceed = await handleFreshInstallation(claudeDir, ctx.prompts);
83054
84094
  if (!canProceed) {
83055
84095
  return { ...ctx, cancelled: true };
@@ -83069,7 +84109,7 @@ async function handleSelection(ctx) {
83069
84109
  let currentVersion = null;
83070
84110
  try {
83071
84111
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
83072
- const claudeDir = prefix ? join120(resolvedDir, prefix) : resolvedDir;
84112
+ const claudeDir = prefix ? join123(resolvedDir, prefix) : resolvedDir;
83073
84113
  const existingMetadata = await readManifest(claudeDir);
83074
84114
  currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
83075
84115
  if (currentVersion) {
@@ -83157,7 +84197,7 @@ async function handleSelection(ctx) {
83157
84197
  if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && releaseTag && !isOfflineMode) {
83158
84198
  try {
83159
84199
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
83160
- const claudeDir = prefix ? join120(resolvedDir, prefix) : resolvedDir;
84200
+ const claudeDir = prefix ? join123(resolvedDir, prefix) : resolvedDir;
83161
84201
  const existingMetadata = await readManifest(claudeDir);
83162
84202
  const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
83163
84203
  if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
@@ -83180,7 +84220,7 @@ async function handleSelection(ctx) {
83180
84220
  let currentSecondaryVersion = null;
83181
84221
  try {
83182
84222
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
83183
- const claudeDir = prefix ? join120(resolvedDir, prefix) : resolvedDir;
84223
+ const claudeDir = prefix ? join123(resolvedDir, prefix) : resolvedDir;
83184
84224
  const existingMetadata = await readManifest(claudeDir);
83185
84225
  currentSecondaryVersion = existingMetadata?.kits?.[secondaryKit]?.version || null;
83186
84226
  } catch {}
@@ -83264,12 +84304,12 @@ function resolveGlobalTargetDir(targetAgents2) {
83264
84304
  // src/commands/init/phases/sync-handler.ts
83265
84305
  init_paths();
83266
84306
  import { copyFile as copyFile7, mkdir as mkdir28, open as open3, readFile as readFile43, rename as rename8, stat as stat13, unlink as unlink11, writeFile as writeFile29 } from "node:fs/promises";
83267
- import { dirname as dirname35, join as join123, resolve as resolve29 } from "node:path";
84307
+ import { dirname as dirname35, join as join126, resolve as resolve29 } from "node:path";
83268
84308
 
83269
84309
  // src/domains/sync/config-version-checker.ts
83270
84310
  init_auth_client();
83271
84311
  import { mkdir as mkdir27, readFile as readFile41, unlink as unlink10, writeFile as writeFile28 } from "node:fs/promises";
83272
- import { join as join121 } from "node:path";
84312
+ import { join as join124 } from "node:path";
83273
84313
  init_version_utils();
83274
84314
  init_logger();
83275
84315
  init_path_resolver();
@@ -83305,12 +84345,12 @@ var CACHE_FILENAME = "config-update-cache.json";
83305
84345
  class ConfigVersionChecker {
83306
84346
  static getCacheFilePath(kitType, global3) {
83307
84347
  const cacheDir = PathResolver.getCacheDir(global3);
83308
- return join121(cacheDir, `${kitType}-${CACHE_FILENAME}`);
84348
+ return join124(cacheDir, `${kitType}-${CACHE_FILENAME}`);
83309
84349
  }
83310
84350
  static async loadCache(kitType, global3) {
83311
84351
  try {
83312
- const cachePath = ConfigVersionChecker.getCacheFilePath(kitType, global3);
83313
- const data = await readFile41(cachePath, "utf8");
84352
+ const cachePath2 = ConfigVersionChecker.getCacheFilePath(kitType, global3);
84353
+ const data = await readFile41(cachePath2, "utf8");
83314
84354
  const parsed = JSON.parse(data);
83315
84355
  if (typeof parsed !== "object" || parsed === null || typeof parsed.lastCheck !== "number" || typeof parsed.latestVersion !== "string" || !parsed.latestVersion || parsed.lastCheck < 0 || parsed.lastCheck > Date.now() + 7 * 24 * 60 * 60 * 1000) {
83316
84356
  logger.debug("Invalid cache structure, ignoring");
@@ -83323,10 +84363,10 @@ class ConfigVersionChecker {
83323
84363
  }
83324
84364
  static async saveCache(kitType, global3, cache3) {
83325
84365
  try {
83326
- const cachePath = ConfigVersionChecker.getCacheFilePath(kitType, global3);
84366
+ const cachePath2 = ConfigVersionChecker.getCacheFilePath(kitType, global3);
83327
84367
  const cacheDir = PathResolver.getCacheDir(global3);
83328
84368
  await mkdir27(cacheDir, { recursive: true });
83329
- await writeFile28(cachePath, JSON.stringify(cache3, null, 2));
84369
+ await writeFile28(cachePath2, JSON.stringify(cache3, null, 2));
83330
84370
  } catch (error) {
83331
84371
  logger.debug(`Cache write failed: ${error instanceof Error ? error.message : "Unknown error"}`);
83332
84372
  }
@@ -83410,9 +84450,9 @@ class ConfigVersionChecker {
83410
84450
  };
83411
84451
  }
83412
84452
  static async clearCache(kitType, global3 = false) {
83413
- const cachePath = ConfigVersionChecker.getCacheFilePath(kitType, global3);
84453
+ const cachePath2 = ConfigVersionChecker.getCacheFilePath(kitType, global3);
83414
84454
  try {
83415
- await unlink10(cachePath);
84455
+ await unlink10(cachePath2);
83416
84456
  logger.debug(`Cleared sync cache for ${kitType}`);
83417
84457
  } catch (error) {
83418
84458
  if (error.code !== "ENOENT") {
@@ -83425,7 +84465,7 @@ class ConfigVersionChecker {
83425
84465
  init_ownership_checker();
83426
84466
  init_logger();
83427
84467
  import { lstat as lstat9, readFile as readFile42, readlink, realpath as realpath3, stat as stat12 } from "node:fs/promises";
83428
- import { isAbsolute as isAbsolute5, join as join122, normalize as normalize9, relative as relative18 } from "node:path";
84468
+ import { isAbsolute as isAbsolute5, join as join125, normalize as normalize9, relative as relative18 } from "node:path";
83429
84469
  var MAX_SYNC_FILE_SIZE = 10 * 1024 * 1024;
83430
84470
  var MAX_SYMLINK_DEPTH = 20;
83431
84471
  async function validateSymlinkChain(path11, basePath, maxDepth = MAX_SYMLINK_DEPTH) {
@@ -83437,7 +84477,7 @@ async function validateSymlinkChain(path11, basePath, maxDepth = MAX_SYMLINK_DEP
83437
84477
  if (!stats.isSymbolicLink())
83438
84478
  break;
83439
84479
  const target = await readlink(current);
83440
- const resolvedTarget = isAbsolute5(target) ? target : join122(current, "..", target);
84480
+ const resolvedTarget = isAbsolute5(target) ? target : join125(current, "..", target);
83441
84481
  const normalizedTarget = normalize9(resolvedTarget);
83442
84482
  const rel = relative18(basePath, normalizedTarget);
83443
84483
  if (rel.startsWith("..") || isAbsolute5(rel)) {
@@ -83473,7 +84513,7 @@ async function validateSyncPath(basePath, filePath) {
83473
84513
  if (normalized.startsWith("..") || normalized.includes("/../")) {
83474
84514
  throw new Error(`Path traversal not allowed: ${filePath}`);
83475
84515
  }
83476
- const fullPath = join122(basePath, normalized);
84516
+ const fullPath = join125(basePath, normalized);
83477
84517
  const rel = relative18(basePath, fullPath);
83478
84518
  if (rel.startsWith("..") || isAbsolute5(rel)) {
83479
84519
  throw new Error(`Path escapes base directory: ${filePath}`);
@@ -83488,7 +84528,7 @@ async function validateSyncPath(basePath, filePath) {
83488
84528
  }
83489
84529
  } catch (error) {
83490
84530
  if (error.code === "ENOENT") {
83491
- const parentPath = join122(fullPath, "..");
84531
+ const parentPath = join125(fullPath, "..");
83492
84532
  try {
83493
84533
  const resolvedBase = await realpath3(basePath);
83494
84534
  const resolvedParent = await realpath3(parentPath);
@@ -83979,7 +85019,7 @@ function getLockTimeout() {
83979
85019
  var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
83980
85020
  async function acquireSyncLock(global3) {
83981
85021
  const cacheDir = PathResolver.getCacheDir(global3);
83982
- const lockPath2 = join123(cacheDir, ".sync-lock");
85022
+ const lockPath2 = join126(cacheDir, ".sync-lock");
83983
85023
  const startTime = Date.now();
83984
85024
  const lockTimeout = getLockTimeout();
83985
85025
  await mkdir28(dirname35(lockPath2), { recursive: true });
@@ -84060,7 +85100,7 @@ async function executeSyncMerge(ctx) {
84060
85100
  try {
84061
85101
  const sourcePath = await validateSyncPath(upstreamDir, file.path);
84062
85102
  const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
84063
- const targetDir = join123(targetPath, "..");
85103
+ const targetDir = join126(targetPath, "..");
84064
85104
  try {
84065
85105
  await mkdir28(targetDir, { recursive: true });
84066
85106
  } catch (mkdirError) {
@@ -84231,7 +85271,7 @@ async function createBackup(claudeDir, files, backupDir) {
84231
85271
  const sourcePath = await validateSyncPath(claudeDir, file.path);
84232
85272
  if (await import_fs_extra36.pathExists(sourcePath)) {
84233
85273
  const targetPath = await validateSyncPath(backupDir, file.path);
84234
- const targetDir = join123(targetPath, "..");
85274
+ const targetDir = join126(targetPath, "..");
84235
85275
  await mkdir28(targetDir, { recursive: true });
84236
85276
  await copyFile7(sourcePath, targetPath);
84237
85277
  }
@@ -84257,38 +85297,38 @@ init_logger();
84257
85297
  init_types2();
84258
85298
  var import_fs_extra37 = __toESM(require_lib(), 1);
84259
85299
  import { rename as rename9, rm as rm10 } from "node:fs/promises";
84260
- import { join as join124, relative as relative19 } from "node:path";
85300
+ import { join as join127, relative as relative19 } from "node:path";
84261
85301
  async function collectDirsToRename(extractDir, folders) {
84262
85302
  const dirsToRename = [];
84263
85303
  if (folders.docs !== DEFAULT_FOLDERS.docs) {
84264
- const docsPath = join124(extractDir, DEFAULT_FOLDERS.docs);
85304
+ const docsPath = join127(extractDir, DEFAULT_FOLDERS.docs);
84265
85305
  if (await import_fs_extra37.pathExists(docsPath)) {
84266
85306
  dirsToRename.push({
84267
85307
  from: docsPath,
84268
- to: join124(extractDir, folders.docs)
85308
+ to: join127(extractDir, folders.docs)
84269
85309
  });
84270
85310
  }
84271
- const claudeDocsPath = join124(extractDir, ".claude", DEFAULT_FOLDERS.docs);
85311
+ const claudeDocsPath = join127(extractDir, ".claude", DEFAULT_FOLDERS.docs);
84272
85312
  if (await import_fs_extra37.pathExists(claudeDocsPath)) {
84273
85313
  dirsToRename.push({
84274
85314
  from: claudeDocsPath,
84275
- to: join124(extractDir, ".claude", folders.docs)
85315
+ to: join127(extractDir, ".claude", folders.docs)
84276
85316
  });
84277
85317
  }
84278
85318
  }
84279
85319
  if (folders.plans !== DEFAULT_FOLDERS.plans) {
84280
- const plansPath = join124(extractDir, DEFAULT_FOLDERS.plans);
85320
+ const plansPath = join127(extractDir, DEFAULT_FOLDERS.plans);
84281
85321
  if (await import_fs_extra37.pathExists(plansPath)) {
84282
85322
  dirsToRename.push({
84283
85323
  from: plansPath,
84284
- to: join124(extractDir, folders.plans)
85324
+ to: join127(extractDir, folders.plans)
84285
85325
  });
84286
85326
  }
84287
- const claudePlansPath = join124(extractDir, ".claude", DEFAULT_FOLDERS.plans);
85327
+ const claudePlansPath = join127(extractDir, ".claude", DEFAULT_FOLDERS.plans);
84288
85328
  if (await import_fs_extra37.pathExists(claudePlansPath)) {
84289
85329
  dirsToRename.push({
84290
85330
  from: claudePlansPath,
84291
- to: join124(extractDir, ".claude", folders.plans)
85331
+ to: join127(extractDir, ".claude", folders.plans)
84292
85332
  });
84293
85333
  }
84294
85334
  }
@@ -84329,7 +85369,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
84329
85369
  init_logger();
84330
85370
  init_types2();
84331
85371
  import { readFile as readFile44, readdir as readdir30, writeFile as writeFile30 } from "node:fs/promises";
84332
- import { join as join125, relative as relative20 } from "node:path";
85372
+ import { join as join128, relative as relative20 } from "node:path";
84333
85373
  var TRANSFORMABLE_FILE_PATTERNS = [
84334
85374
  ".md",
84335
85375
  ".txt",
@@ -84382,7 +85422,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
84382
85422
  let replacementsCount = 0;
84383
85423
  const entries = await readdir30(dir, { withFileTypes: true });
84384
85424
  for (const entry of entries) {
84385
- const fullPath = join125(dir, entry.name);
85425
+ const fullPath = join128(dir, entry.name);
84386
85426
  if (entry.isDirectory()) {
84387
85427
  if (entry.name === "node_modules" || entry.name === ".git") {
84388
85428
  continue;
@@ -84518,9 +85558,9 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
84518
85558
  // src/services/transformers/global-path-transformer.ts
84519
85559
  init_logger();
84520
85560
  import { readFile as readFile45, readdir as readdir31, writeFile as writeFile31 } from "node:fs/promises";
84521
- import { platform as platform11 } from "node:os";
84522
- import { extname as extname8, join as join126 } from "node:path";
84523
- var IS_WINDOWS3 = platform11() === "win32";
85561
+ import { platform as platform12 } from "node:os";
85562
+ import { extname as extname8, join as join129 } from "node:path";
85563
+ var IS_WINDOWS3 = platform12() === "win32";
84524
85564
  var HOME_PREFIX = "$HOME";
84525
85565
  function getHomeDirPrefix() {
84526
85566
  return HOME_PREFIX;
@@ -84619,7 +85659,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
84619
85659
  async function processDirectory2(dir) {
84620
85660
  const entries = await readdir31(dir, { withFileTypes: true });
84621
85661
  for (const entry of entries) {
84622
- const fullPath = join126(dir, entry.name);
85662
+ const fullPath = join129(dir, entry.name);
84623
85663
  if (entry.isDirectory()) {
84624
85664
  if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
84625
85665
  continue;
@@ -84912,8 +85952,8 @@ init_dist2();
84912
85952
 
84913
85953
  // src/domains/mcp/agent-detector.ts
84914
85954
  init_environment();
84915
- import { existsSync as existsSync58 } from "node:fs";
84916
- import { join as join127 } from "node:path";
85955
+ import { existsSync as existsSync60 } from "node:fs";
85956
+ import { join as join130 } from "node:path";
84917
85957
 
84918
85958
  // src/domains/mcp/shell-out.ts
84919
85959
  import { spawnSync as spawnSync5 } from "node:child_process";
@@ -85003,9 +86043,9 @@ function getAgentConfigPath(agent) {
85003
86043
  return null;
85004
86044
  switch (agent) {
85005
86045
  case "claude-code":
85006
- return join127(home6, ".claude.json");
86046
+ return join130(home6, ".claude.json");
85007
86047
  case "codex":
85008
- return join127(home6, ".codex", "config.toml");
86048
+ return join130(home6, ".codex", "config.toml");
85009
86049
  default: {
85010
86050
  const _exhaustive = agent;
85011
86051
  return _exhaustive;
@@ -85014,7 +86054,7 @@ function getAgentConfigPath(agent) {
85014
86054
  }
85015
86055
  var defaultCheckers = {
85016
86056
  binaryOnPath: isBinaryOnPath,
85017
- configExists: existsSync58
86057
+ configExists: existsSync60
85018
86058
  };
85019
86059
  function isAgentPresent(agent, checkers = defaultCheckers) {
85020
86060
  if (checkers.binaryOnPath(AGENT_BINARY[agent])) {
@@ -85030,8 +86070,8 @@ var PROJECT_MARKERS = {
85030
86070
  "claude-code": [".claude", "CLAUDE.md"],
85031
86071
  codex: [".codex", "AGENTS.md"]
85032
86072
  };
85033
- function detectProjectAgents(cwd2 = process.cwd(), exists2 = existsSync58) {
85034
- return ALL_MCP_AGENTS.filter((agent) => PROJECT_MARKERS[agent].some((marker) => exists2(join127(cwd2, marker))));
86073
+ function detectProjectAgents(cwd2 = process.cwd(), exists2 = existsSync60) {
86074
+ return ALL_MCP_AGENTS.filter((agent) => PROJECT_MARKERS[agent].some((marker) => exists2(join130(cwd2, marker))));
85035
86075
  }
85036
86076
 
85037
86077
  // src/domains/mcp/registry-client.ts
@@ -85043,12 +86083,12 @@ init_auth_client();
85043
86083
  init_logger();
85044
86084
  init_paths2();
85045
86085
  import { promises as fs33 } from "node:fs";
85046
- import { join as join128 } from "node:path";
86086
+ import { join as join131 } from "node:path";
85047
86087
  function getCacheDir() {
85048
- return join128(getConfigDir(), "mcp");
86088
+ return join131(getConfigDir(), "mcp");
85049
86089
  }
85050
86090
  function getCachePath2() {
85051
- return join128(getCacheDir(), "registry-cache.json");
86091
+ return join131(getCacheDir(), "registry-cache.json");
85052
86092
  }
85053
86093
  async function readCachedRegistry() {
85054
86094
  try {
@@ -85177,16 +86217,16 @@ function resolveService(registry, name2) {
85177
86217
  }
85178
86218
 
85179
86219
  // src/domains/mcp/writers/claude-config-file.ts
85180
- import { existsSync as existsSync59 } from "node:fs";
86220
+ import { existsSync as existsSync61 } from "node:fs";
85181
86221
  import { mkdir as mkdir29, writeFile as writeFile32 } from "node:fs/promises";
85182
- import { dirname as dirname36, join as join129 } from "node:path";
86222
+ import { dirname as dirname36, join as join132 } from "node:path";
85183
86223
  var AGENT = "claude-code";
85184
86224
  var LOCAL_SCOPE_FALLBACK_WARNING = "claude CLI not found; local scope isn't representable via direct file write, wrote to user-level ~/.claude.json instead";
85185
86225
  function userConfigPath() {
85186
86226
  return getAgentConfigPath(AGENT);
85187
86227
  }
85188
86228
  function projectConfigPath() {
85189
- return join129(process.cwd(), ".mcp.json");
86229
+ return join132(process.cwd(), ".mcp.json");
85190
86230
  }
85191
86231
  function configPathFor(scope) {
85192
86232
  return scope === "project" ? projectConfigPath() : userConfigPath();
@@ -85225,7 +86265,7 @@ async function fileAdd(entry, scope) {
85225
86265
  }
85226
86266
  async function fileRemove(name2, scope) {
85227
86267
  const path11 = configPathFor(scope);
85228
- if (!path11 || !existsSync59(path11)) {
86268
+ if (!path11 || !existsSync61(path11)) {
85229
86269
  return { agent: AGENT, status: "skipped", detail: "No config file present" };
85230
86270
  }
85231
86271
  const existing = await readJsonConfigFile(path11);
@@ -85340,7 +86380,7 @@ var claudeWriter = {
85340
86380
 
85341
86381
  // src/domains/mcp/writers/codex-writer.ts
85342
86382
  init_path_safety();
85343
- import { existsSync as existsSync60 } from "node:fs";
86383
+ import { existsSync as existsSync62 } from "node:fs";
85344
86384
  import { readFile as readFile47, writeFile as writeFile33 } from "node:fs/promises";
85345
86385
 
85346
86386
  // src/domains/mcp/writers/codex-config-file.ts
@@ -85431,7 +86471,7 @@ async function fileAdd2(entry, scope) {
85431
86471
  }
85432
86472
  async function fileRemove2(name2) {
85433
86473
  const path11 = configPath();
85434
- if (!path11 || !existsSync60(path11)) {
86474
+ if (!path11 || !existsSync62(path11)) {
85435
86475
  return { agent: AGENT3, status: "skipped", detail: "No config file present" };
85436
86476
  }
85437
86477
  try {
@@ -85510,7 +86550,7 @@ async function remove13(name2, opts) {
85510
86550
  }
85511
86551
  async function listConfigured() {
85512
86552
  const path11 = configPath();
85513
- if (!path11 || !existsSync60(path11))
86553
+ if (!path11 || !existsSync62(path11))
85514
86554
  return { has: () => false };
85515
86555
  try {
85516
86556
  const content = await readFile47(path11, "utf-8");
@@ -85866,19 +86906,19 @@ async function mcpCommand(action, service, options2 = {}) {
85866
86906
  }
85867
86907
  // src/commands/plan/plan-command.ts
85868
86908
  init_output_manager();
85869
- import { existsSync as existsSync65, statSync as statSync11 } from "node:fs";
85870
- import { dirname as dirname42, join as join133, parse as parse4, resolve as resolve33 } from "node:path";
86909
+ import { existsSync as existsSync67, statSync as statSync12 } from "node:fs";
86910
+ import { dirname as dirname42, join as join136, parse as parse4, resolve as resolve33 } from "node:path";
85871
86911
 
85872
86912
  // src/commands/plan/plan-read-handlers.ts
85873
- import { existsSync as existsSync64, statSync as statSync10 } from "node:fs";
85874
- import { basename as basename21, dirname as dirname41, join as join132, relative as relative21, resolve as resolve31 } from "node:path";
86913
+ import { existsSync as existsSync66, statSync as statSync11 } from "node:fs";
86914
+ import { basename as basename21, dirname as dirname41, join as join135, relative as relative21, resolve as resolve31 } from "node:path";
85875
86915
 
85876
86916
  // src/domains/plan-parser/index.ts
85877
86917
  import { dirname as dirname40 } from "node:path";
85878
86918
 
85879
86919
  // src/domains/plan-parser/plan-table-parser.ts
85880
86920
  var import_gray_matter6 = __toESM(require_gray_matter(), 1);
85881
- import { readFileSync as readFileSync23 } from "node:fs";
86921
+ import { readFileSync as readFileSync24 } from "node:fs";
85882
86922
  import { dirname as dirname37, resolve as resolve30 } from "node:path";
85883
86923
  function normalizeStatus(raw) {
85884
86924
  const s3 = raw.toLowerCase().trim();
@@ -86244,30 +87284,30 @@ function parsePhasesFromBody(body, dir, options2) {
86244
87284
  return parseFormat6(normalizedBody, dir, options2);
86245
87285
  }
86246
87286
  function parsePlanFile(planFilePath, options2) {
86247
- const content = readFileSync23(planFilePath, "utf8");
87287
+ const content = readFileSync24(planFilePath, "utf8");
86248
87288
  const dir = dirname37(planFilePath);
86249
87289
  const { data: frontmatter, content: body } = import_gray_matter6.default(content);
86250
87290
  const phases = parsePhasesFromBody(body, dir, options2);
86251
87291
  return { frontmatter, phases };
86252
87292
  }
86253
87293
  // src/domains/plan-parser/plan-scanner.ts
86254
- import { existsSync as existsSync61, readdirSync as readdirSync10 } from "node:fs";
86255
- import { join as join130 } from "node:path";
87294
+ import { existsSync as existsSync63, readdirSync as readdirSync11 } from "node:fs";
87295
+ import { join as join133 } from "node:path";
86256
87296
  function scanPlanDir(dir) {
86257
- if (!existsSync61(dir))
87297
+ if (!existsSync63(dir))
86258
87298
  return [];
86259
87299
  try {
86260
- return readdirSync10(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join130(dir, entry.name, "plan.md")).filter(existsSync61);
87300
+ return readdirSync11(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join133(dir, entry.name, "plan.md")).filter(existsSync63);
86261
87301
  } catch {
86262
87302
  return [];
86263
87303
  }
86264
87304
  }
86265
87305
  // src/domains/plan-parser/plan-validator.ts
86266
87306
  var import_gray_matter7 = __toESM(require_gray_matter(), 1);
86267
- import { existsSync as existsSync62, readFileSync as readFileSync24 } from "node:fs";
87307
+ import { existsSync as existsSync64, readFileSync as readFileSync25 } from "node:fs";
86268
87308
  import { basename as basename19, dirname as dirname38 } from "node:path";
86269
87309
  function validatePlanFile(filePath, strict = false) {
86270
- const content = readFileSync24(filePath, "utf8");
87310
+ const content = readFileSync25(filePath, "utf8");
86271
87311
  const dir = dirname38(filePath);
86272
87312
  const issues = [];
86273
87313
  const lines = content.split(`
@@ -86304,7 +87344,7 @@ function validatePlanFile(filePath, strict = false) {
86304
87344
  });
86305
87345
  }
86306
87346
  for (const phase of phases) {
86307
- if (phase.file && !existsSync62(phase.file)) {
87347
+ if (phase.file && !existsSync64(phase.file)) {
86308
87348
  const fileBasename = basename19(phase.file);
86309
87349
  const refLine = lines.findIndex((l2) => l2.includes(fileBasename));
86310
87350
  issues.push({
@@ -86324,9 +87364,9 @@ function validatePlanFile(filePath, strict = false) {
86324
87364
  }
86325
87365
  // src/domains/plan-parser/plan-writer.ts
86326
87366
  var import_gray_matter8 = __toESM(require_gray_matter(), 1);
86327
- import { mkdirSync as mkdirSync9, readFileSync as readFileSync25, writeFileSync as writeFileSync12 } from "node:fs";
86328
- import { existsSync as existsSync63 } from "node:fs";
86329
- import { basename as basename20, dirname as dirname39, join as join131 } from "node:path";
87367
+ import { mkdirSync as mkdirSync10, readFileSync as readFileSync26, writeFileSync as writeFileSync13 } from "node:fs";
87368
+ import { existsSync as existsSync65 } from "node:fs";
87369
+ import { basename as basename20, dirname as dirname39, join as join134 } from "node:path";
86330
87370
  function phaseNameToFilename(id, name2) {
86331
87371
  const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
86332
87372
  const num4 = numMatch ? numMatch[1] : id;
@@ -86431,16 +87471,16 @@ function resolvePhaseIds(phases) {
86431
87471
  }
86432
87472
  function scaffoldPlan(options2) {
86433
87473
  const { dir } = options2;
86434
- mkdirSync9(dir, { recursive: true });
87474
+ mkdirSync10(dir, { recursive: true });
86435
87475
  const resolvedPhases = resolvePhaseIds(options2.phases);
86436
87476
  const optionsWithResolved = { ...options2, phases: resolvedPhases };
86437
- const planFile = join131(dir, "plan.md");
86438
- writeFileSync12(planFile, generatePlanMd(optionsWithResolved), "utf8");
87477
+ const planFile = join134(dir, "plan.md");
87478
+ writeFileSync13(planFile, generatePlanMd(optionsWithResolved), "utf8");
86439
87479
  const phaseFiles = [];
86440
87480
  for (const phase of resolvedPhases) {
86441
87481
  const filename = phaseNameToFilename(phase.id, phase.name);
86442
- const phaseFile = join131(dir, filename);
86443
- writeFileSync12(phaseFile, generatePhaseTemplate(phase), "utf8");
87482
+ const phaseFile = join134(dir, filename);
87483
+ writeFileSync13(phaseFile, generatePhaseTemplate(phase), "utf8");
86444
87484
  phaseFiles.push(phaseFile);
86445
87485
  }
86446
87486
  return { planFile, phaseFiles };
@@ -86464,7 +87504,7 @@ function isCanonicalFormat(content) {
86464
87504
  return /^\|\s*phase\s*\|\s*name\s*\|\s*status\s*\|/im.test(content);
86465
87505
  }
86466
87506
  function updatePhaseStatus(planFile, phaseId, newStatus) {
86467
- const raw = readFileSync25(planFile, "utf8").replace(/\r\n/g, `
87507
+ const raw = readFileSync26(planFile, "utf8").replace(/\r\n/g, `
86468
87508
  `);
86469
87509
  if (!isCanonicalFormat(raw)) {
86470
87510
  console.error("[!] plan.md is not in canonical format — skipping status update");
@@ -86504,10 +87544,10 @@ function updatePhaseStatus(planFile, phaseId, newStatus) {
86504
87544
  }
86505
87545
  const updatedFrontmatter = { ...frontmatter, status: planStatus };
86506
87546
  const updatedContent = import_gray_matter8.default.stringify(updatedBody, updatedFrontmatter);
86507
- writeFileSync12(planFile, updatedContent, "utf8");
87547
+ writeFileSync13(planFile, updatedContent, "utf8");
86508
87548
  const planDir = dirname39(planFile);
86509
87549
  const phaseFilename = phaseNameFilenameFromTableRow(updatedBody, phaseId, planDir);
86510
- if (phaseFilename && existsSync63(phaseFilename)) {
87550
+ if (phaseFilename && existsSync65(phaseFilename)) {
86511
87551
  updatePhaseFileFrontmatter(phaseFilename, newStatus);
86512
87552
  }
86513
87553
  }
@@ -86519,18 +87559,18 @@ function phaseNameFilenameFromTableRow(body, phaseId, planDir) {
86519
87559
  continue;
86520
87560
  const linkMatch = /\[([^\]]+)\]\(\.\/([^)]+)\)/.exec(row);
86521
87561
  if (linkMatch)
86522
- return join131(planDir, linkMatch[2]);
87562
+ return join134(planDir, linkMatch[2]);
86523
87563
  }
86524
87564
  return null;
86525
87565
  }
86526
87566
  function updatePhaseFileFrontmatter(phaseFile, newStatus) {
86527
- const raw = readFileSync25(phaseFile, "utf8");
87567
+ const raw = readFileSync26(phaseFile, "utf8");
86528
87568
  const { data: frontmatter, content: body } = import_gray_matter8.default(raw);
86529
87569
  const updated = { ...frontmatter, status: newStatus };
86530
- writeFileSync12(phaseFile, import_gray_matter8.default.stringify(body, updated), "utf8");
87570
+ writeFileSync13(phaseFile, import_gray_matter8.default.stringify(body, updated), "utf8");
86531
87571
  }
86532
87572
  function addPhase(planFile, name2, afterId) {
86533
- const raw = readFileSync25(planFile, "utf8").replace(/\r\n/g, `
87573
+ const raw = readFileSync26(planFile, "utf8").replace(/\r\n/g, `
86534
87574
  `);
86535
87575
  if (!isCanonicalFormat(raw)) {
86536
87576
  console.error("[!] plan.md is not in canonical format — cannot add phase");
@@ -86599,9 +87639,9 @@ function addPhase(planFile, name2, afterId) {
86599
87639
  updatedBody = lines.join(`
86600
87640
  `);
86601
87641
  }
86602
- writeFileSync12(planFile, import_gray_matter8.default.stringify(updatedBody, frontmatter), "utf8");
86603
- const phaseFilePath = join131(planDir, filename);
86604
- writeFileSync12(phaseFilePath, generatePhaseTemplate({ id: phaseId, name: name2 }), "utf8");
87642
+ writeFileSync13(planFile, import_gray_matter8.default.stringify(updatedBody, frontmatter), "utf8");
87643
+ const phaseFilePath = join134(planDir, filename);
87644
+ writeFileSync13(phaseFilePath, generatePhaseTemplate({ id: phaseId, name: name2 }), "utf8");
86605
87645
  return { phaseId, phaseFile: phaseFilePath };
86606
87646
  }
86607
87647
 
@@ -86704,7 +87744,7 @@ async function handleValidate(target, options2) {
86704
87744
  }
86705
87745
  async function handleStatus(target, options2) {
86706
87746
  const t = target ? resolve31(target) : null;
86707
- const plansDir = t && existsSync64(t) && statSync10(t).isDirectory() && !existsSync64(join132(t, "plan.md")) ? t : null;
87747
+ const plansDir = t && existsSync66(t) && statSync11(t).isDirectory() && !existsSync66(join135(t, "plan.md")) ? t : null;
86708
87748
  if (plansDir) {
86709
87749
  const planFiles = scanPlanDir(plansDir);
86710
87750
  if (planFiles.length === 0) {
@@ -86935,20 +87975,20 @@ async function handleAddPhase(target, options2) {
86935
87975
  // src/commands/plan/plan-command.ts
86936
87976
  function resolvePlanFile(target) {
86937
87977
  const t = target ? resolve33(target) : process.cwd();
86938
- if (existsSync65(t)) {
86939
- const stat14 = statSync11(t);
87978
+ if (existsSync67(t)) {
87979
+ const stat14 = statSync12(t);
86940
87980
  if (stat14.isFile())
86941
87981
  return t;
86942
- const candidate = join133(t, "plan.md");
86943
- if (existsSync65(candidate))
87982
+ const candidate = join136(t, "plan.md");
87983
+ if (existsSync67(candidate))
86944
87984
  return candidate;
86945
87985
  }
86946
87986
  if (!target) {
86947
87987
  let dir = process.cwd();
86948
87988
  const root = parse4(dir).root;
86949
87989
  while (dir !== root) {
86950
- const candidate = join133(dir, "plan.md");
86951
- if (existsSync65(candidate))
87990
+ const candidate = join136(dir, "plan.md");
87991
+ if (existsSync67(candidate))
86952
87992
  return candidate;
86953
87993
  dir = dirname42(dir);
86954
87994
  }
@@ -86998,7 +88038,7 @@ async function planCommand(action, target, options2) {
86998
88038
  let resolvedTarget = target;
86999
88039
  if (resolvedAction && !knownActions.has(resolvedAction)) {
87000
88040
  const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
87001
- const existsOnDisk = !looksLikePath && existsSync65(resolve33(resolvedAction));
88041
+ const existsOnDisk = !looksLikePath && existsSync67(resolve33(resolvedAction));
87002
88042
  if (looksLikePath || existsOnDisk) {
87003
88043
  resolvedTarget = resolvedAction;
87004
88044
  resolvedAction = undefined;
@@ -87035,6 +88075,791 @@ async function planCommand(action, target, options2) {
87035
88075
  process.exitCode = 1;
87036
88076
  }
87037
88077
  }
88078
+ // src/commands/statusline/statusline-command.ts
88079
+ import { appendFileSync as appendFileSync3 } from "node:fs";
88080
+ import { homedir as homedir31 } from "node:os";
88081
+ init_cache_dir();
88082
+
88083
+ // src/domains/statusline/config-loader.ts
88084
+ init_takumi_config_manager();
88085
+
88086
+ // src/domains/statusline/config.ts
88087
+ var PRESET_PROMPTS = {
88088
+ full: "$brand $model $context $quotas $directory $git $activity",
88089
+ compact: "$model $context $quotas $directory $git",
88090
+ minimal: "$model $context $directory",
88091
+ none: ""
88092
+ };
88093
+ var DEFAULT_STATUSLINE_SETTINGS = {
88094
+ prompt: PRESET_PROMPTS.full,
88095
+ brand: {
88096
+ icon: "◆",
88097
+ showCliVersion: true,
88098
+ showCoreVersion: false,
88099
+ color: "magenta",
88100
+ versionColor: "dim"
88101
+ },
88102
+ model: { color: "brightCyan" },
88103
+ context: {
88104
+ barWidth: 10,
88105
+ barStyle: "geometric",
88106
+ showPercent: true,
88107
+ colors: { low: "brightGreen", mid: "brightYellow", high: "brightRed" },
88108
+ thresholds: { mid: 50, high: 80 }
88109
+ },
88110
+ quotas: { windows: ["5h", "week"], barWidth: 0, showCountdown: true, icon: "⏳" },
88111
+ directory: { icon: "\uD83D\uDCC2", collapseHome: true, truncationLength: 3, color: "yellow" },
88112
+ git: {
88113
+ icon: "✦",
88114
+ showDirty: true,
88115
+ dirtyInBrackets: true,
88116
+ showAheadBehind: true,
88117
+ countUntracked: true,
88118
+ branchColor: "magenta"
88119
+ },
88120
+ activity: { maxAgentRows: 4, todoTruncation: 50 },
88121
+ cost: { icon: "\uD83D\uDCB0", hideZero: true }
88122
+ };
88123
+ function isPreset(value) {
88124
+ return value === "full" || value === "compact" || value === "minimal" || value === "none";
88125
+ }
88126
+ function mergeSettings2(base, override) {
88127
+ const o2 = override;
88128
+ return {
88129
+ prompt: o2.prompt ?? base.prompt,
88130
+ brand: { ...base.brand, ...o2.brand },
88131
+ model: { ...base.model, ...o2.model },
88132
+ context: {
88133
+ ...base.context,
88134
+ ...o2.context,
88135
+ colors: { ...base.context.colors, ...o2.context?.colors },
88136
+ thresholds: { ...base.context.thresholds, ...o2.context?.thresholds }
88137
+ },
88138
+ quotas: { ...base.quotas, ...o2.quotas },
88139
+ directory: { ...base.directory, ...o2.directory },
88140
+ git: { ...base.git, ...o2.git },
88141
+ activity: { ...base.activity, ...o2.activity },
88142
+ cost: { ...base.cost, ...o2.cost }
88143
+ };
88144
+ }
88145
+ function cloneDefaults() {
88146
+ return mergeSettings2(DEFAULT_STATUSLINE_SETTINGS, {});
88147
+ }
88148
+ function resolveStatuslineSettings(raw) {
88149
+ if (raw == null)
88150
+ return cloneDefaults();
88151
+ if (typeof raw === "string") {
88152
+ const prompt = isPreset(raw) ? PRESET_PROMPTS[raw] : PRESET_PROMPTS.full;
88153
+ return { ...cloneDefaults(), prompt };
88154
+ }
88155
+ return mergeSettings2(DEFAULT_STATUSLINE_SETTINGS, raw);
88156
+ }
88157
+
88158
+ // src/domains/statusline/config-loader.ts
88159
+ async function loadStatuslineSettings(cwd2) {
88160
+ try {
88161
+ const { config } = await TakumiConfigManager.loadFull(cwd2);
88162
+ return resolveStatuslineSettings(config.statusline);
88163
+ } catch {
88164
+ return resolveStatuslineSettings(undefined);
88165
+ }
88166
+ }
88167
+
88168
+ // src/domains/statusline/context-usage.ts
88169
+ var AUTOCOMPACT_BUFFER = 40000;
88170
+ function usedTokens(usage2) {
88171
+ if (!usage2)
88172
+ return 0;
88173
+ const { input_tokens, cache_creation_input_tokens, cache_read_input_tokens } = usage2;
88174
+ return (input_tokens ?? 0) + (cache_creation_input_tokens ?? 0) + (cache_read_input_tokens ?? 0);
88175
+ }
88176
+ function computeContextPercent(cw) {
88177
+ const size = cw.context_window_size ?? 0;
88178
+ if (size <= 0)
88179
+ return 0;
88180
+ const reported = cw.used_percentage;
88181
+ if (typeof reported === "number" && reported >= 0)
88182
+ return Math.round(reported);
88183
+ if (size <= AUTOCOMPACT_BUFFER)
88184
+ return 0;
88185
+ const occupied = usedTokens(cw.current_usage) + AUTOCOMPACT_BUFFER;
88186
+ return Math.min(100, Math.round(occupied / size * 100));
88187
+ }
88188
+
88189
+ // src/domains/statusline/git-cache.ts
88190
+ import { createHash as createHash16 } from "node:crypto";
88191
+ import { readFileSync as readFileSync27 } from "node:fs";
88192
+ init_cache_dir();
88193
+ var GIT_CACHE_TTL_MS = 30000;
88194
+ var MAX_UNTRACKED_FILES = 200;
88195
+ var MAX_UNTRACKED_BYTES = 4 * 1024 * 1024;
88196
+ var NEWLINE = 10;
88197
+ function emptySnapshot(branch = "") {
88198
+ return {
88199
+ branch,
88200
+ trackedInsertions: 0,
88201
+ untrackedInsertions: 0,
88202
+ deletions: 0,
88203
+ ahead: 0,
88204
+ behind: 0
88205
+ };
88206
+ }
88207
+ function cachePathFor(cwd2) {
88208
+ const key = createHash16("md5").update(cwd2).digest("hex").slice(0, 8);
88209
+ return getStatuslineCachePath(`git-${key}.json`);
88210
+ }
88211
+ function readFreshCache(cwd2, now) {
88212
+ const raw = readCacheFileSafe(cachePathFor(cwd2));
88213
+ if (!raw)
88214
+ return null;
88215
+ try {
88216
+ const parsed = JSON.parse(raw);
88217
+ if (typeof parsed.timestamp !== "number" || !parsed.data)
88218
+ return null;
88219
+ if (now - parsed.timestamp >= GIT_CACHE_TTL_MS)
88220
+ return null;
88221
+ return parsed.data;
88222
+ } catch {
88223
+ return null;
88224
+ }
88225
+ }
88226
+ function toCount(field) {
88227
+ const n2 = Number.parseInt(field ?? "", 10);
88228
+ return Number.isNaN(n2) ? 0 : n2;
88229
+ }
88230
+ function sumNumstat(numstat) {
88231
+ return numstat.split(`
88232
+ `).filter(Boolean).reduce((acc, row) => {
88233
+ const [added, removed] = row.split("\t");
88234
+ if (added === "-")
88235
+ return acc;
88236
+ acc.insertions += toCount(added);
88237
+ acc.deletions += toCount(removed);
88238
+ return acc;
88239
+ }, { insertions: 0, deletions: 0 });
88240
+ }
88241
+ function trackedDiff(cwd2) {
88242
+ const vsHead = runGit(cwd2, ["diff", "HEAD", "--numstat"], GIT_RENDER_TIMEOUT_MS);
88243
+ if (vsHead)
88244
+ return sumNumstat(vsHead);
88245
+ const staged = runGit(cwd2, ["diff", "--cached", "--numstat"], GIT_RENDER_TIMEOUT_MS);
88246
+ const unstaged = runGit(cwd2, ["diff", "--numstat"], GIT_RENDER_TIMEOUT_MS);
88247
+ return sumNumstat([staged, unstaged].join(`
88248
+ `));
88249
+ }
88250
+ function countBufferLines(buf) {
88251
+ if (buf.length === 0)
88252
+ return 0;
88253
+ let count = 0;
88254
+ for (let idx = buf.indexOf(NEWLINE);idx !== -1; idx = buf.indexOf(NEWLINE, idx + 1)) {
88255
+ count++;
88256
+ }
88257
+ return buf[buf.length - 1] === NEWLINE ? count : count + 1;
88258
+ }
88259
+ function untrackedInsertions(cwd2) {
88260
+ const listing = runGit(cwd2, ["ls-files", "--others", "--exclude-standard"], GIT_RENDER_TIMEOUT_MS);
88261
+ if (!listing)
88262
+ return 0;
88263
+ const files = listing.split(`
88264
+ `).filter(Boolean).slice(0, MAX_UNTRACKED_FILES);
88265
+ let total = 0;
88266
+ let byteBudget = MAX_UNTRACKED_BYTES;
88267
+ for (const relative23 of files) {
88268
+ if (byteBudget <= 0)
88269
+ break;
88270
+ let buf;
88271
+ try {
88272
+ buf = readFileSync27(`${cwd2}/${relative23}`);
88273
+ } catch {
88274
+ continue;
88275
+ }
88276
+ const slice = buf.length > byteBudget ? buf.subarray(0, byteBudget) : buf;
88277
+ total += countBufferLines(slice);
88278
+ byteBudget -= slice.length;
88279
+ }
88280
+ return total;
88281
+ }
88282
+ function aheadBehind(cwd2) {
88283
+ const out = runGit(cwd2, ["rev-list", "--left-right", "--count", "@{u}...HEAD"], GIT_RENDER_TIMEOUT_MS);
88284
+ if (!out)
88285
+ return { ahead: 0, behind: 0 };
88286
+ const [behind, ahead] = out.split(/\s+/);
88287
+ return { ahead: Number.parseInt(ahead, 10) || 0, behind: Number.parseInt(behind, 10) || 0 };
88288
+ }
88289
+ function probe2(cwd2, branch) {
88290
+ const tracked = trackedDiff(cwd2);
88291
+ const { ahead, behind } = aheadBehind(cwd2);
88292
+ return {
88293
+ branch,
88294
+ trackedInsertions: tracked.insertions,
88295
+ untrackedInsertions: untrackedInsertions(cwd2),
88296
+ deletions: tracked.deletions,
88297
+ ahead,
88298
+ behind
88299
+ };
88300
+ }
88301
+ function getGitSnapshot(cwd2) {
88302
+ try {
88303
+ const now = Date.now();
88304
+ const cached = readFreshCache(cwd2, now);
88305
+ if (cached)
88306
+ return cached;
88307
+ const branch = resolveGitBranchOrCommit(cwd2, GIT_RENDER_TIMEOUT_MS);
88308
+ const snapshot = branch ? probe2(cwd2, branch) : emptySnapshot("");
88309
+ const envelope = { timestamp: now, data: snapshot };
88310
+ writeCacheFileSafe(cachePathFor(cwd2), JSON.stringify(envelope));
88311
+ return snapshot;
88312
+ } catch {
88313
+ return emptySnapshot("");
88314
+ }
88315
+ }
88316
+
88317
+ // src/domains/statusline/payload.ts
88318
+ function finiteOrUndefined(value) {
88319
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
88320
+ }
88321
+ function finiteOr0(value) {
88322
+ return finiteOrUndefined(value) ?? 0;
88323
+ }
88324
+ function record(value) {
88325
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
88326
+ }
88327
+ function text(value) {
88328
+ return typeof value === "string" ? value : "";
88329
+ }
88330
+ var NUMERIC_STRING = /^\d+(\.\d+)?$/;
88331
+ function parseCost(value) {
88332
+ if (typeof value === "number")
88333
+ return Number.isFinite(value) ? value : null;
88334
+ if (typeof value === "string" && NUMERIC_STRING.test(value))
88335
+ return Number.parseFloat(value);
88336
+ return null;
88337
+ }
88338
+ function parseContextWindow(value) {
88339
+ const raw = record(value);
88340
+ const usage2 = record(raw.current_usage);
88341
+ return {
88342
+ used_percentage: finiteOrUndefined(raw.used_percentage),
88343
+ context_window_size: finiteOr0(raw.context_window_size),
88344
+ remaining_percentage: finiteOrUndefined(raw.remaining_percentage),
88345
+ current_usage: {
88346
+ input_tokens: finiteOr0(usage2.input_tokens),
88347
+ cache_creation_input_tokens: finiteOr0(usage2.cache_creation_input_tokens),
88348
+ cache_read_input_tokens: finiteOr0(usage2.cache_read_input_tokens)
88349
+ }
88350
+ };
88351
+ }
88352
+ function parseStatusPayload(raw) {
88353
+ const model = record(raw.model);
88354
+ const workspace = record(raw.workspace);
88355
+ const cost = record(raw.cost);
88356
+ const workspaceDir = workspace.current_dir;
88357
+ const cwd2 = typeof workspaceDir === "string" && workspaceDir.length > 0 ? workspaceDir : text(raw.cwd);
88358
+ const displayName = model.display_name;
88359
+ return {
88360
+ sessionId: text(raw.session_id),
88361
+ modelName: typeof displayName === "string" ? displayName : "Claude",
88362
+ cwd: cwd2,
88363
+ contextWindow: parseContextWindow(raw.context_window),
88364
+ costUsd: parseCost(cost.total_cost_usd),
88365
+ linesAdded: finiteOr0(cost.total_lines_added),
88366
+ linesRemoved: finiteOr0(cost.total_lines_removed)
88367
+ };
88368
+ }
88369
+
88370
+ // src/domains/statusline/quota-windows.ts
88371
+ init_usage_limits_cache();
88372
+
88373
+ // src/domains/statusline/time-format.ts
88374
+ function safeGetTime(value) {
88375
+ if (!value)
88376
+ return 0;
88377
+ const ms2 = value instanceof Date ? value.getTime() : new Date(value).getTime();
88378
+ return Number.isNaN(ms2) ? 0 : ms2;
88379
+ }
88380
+ function formatElapsed(start2, end) {
88381
+ const from = safeGetTime(start2);
88382
+ if (!from)
88383
+ return "0s";
88384
+ const to2 = end == null ? Date.now() : safeGetTime(end) || Date.now();
88385
+ const span = to2 - from;
88386
+ if (span < 1000)
88387
+ return "<1s";
88388
+ if (span < 60000)
88389
+ return `${Math.round(span / 1000)}s`;
88390
+ const minutes = Math.floor(span / 60000);
88391
+ const seconds = Math.round(span % 60000 / 1000);
88392
+ return `${minutes}m ${seconds}s`;
88393
+ }
88394
+ function formatCountdown(msLeft) {
88395
+ if (!Number.isFinite(msLeft) || msLeft <= 0)
88396
+ return "";
88397
+ const totalMinutes = Math.floor(msLeft / 60000);
88398
+ if (totalMinutes < 60)
88399
+ return `${totalMinutes}m`;
88400
+ if (totalMinutes < 1440) {
88401
+ const hours = Math.floor(totalMinutes / 60);
88402
+ const minutes = totalMinutes % 60;
88403
+ return minutes === 0 ? `${hours}h` : `${hours}h${minutes}m`;
88404
+ }
88405
+ return `${Math.floor(totalMinutes / 1440)}d`;
88406
+ }
88407
+
88408
+ // src/domains/statusline/quota-windows.ts
88409
+ var RENDER_TTL_MS = 300000;
88410
+ var FIVE_HOUR_LABEL = "5h";
88411
+ var WEEK_LABEL = "wk";
88412
+ function pushSnapshotWindow(into, label, percent, resetsAt, now) {
88413
+ if (percent == null)
88414
+ return;
88415
+ let text2 = `${label} ${percent}%`;
88416
+ if (resetsAt) {
88417
+ const countdown = formatCountdown(new Date(resetsAt).getTime() - now);
88418
+ if (countdown)
88419
+ text2 += ` (${countdown})`;
88420
+ }
88421
+ into.push(text2);
88422
+ }
88423
+ function fromSnapshot(snapshot, data, now) {
88424
+ if (!snapshot)
88425
+ return [];
88426
+ const windows = [];
88427
+ pushSnapshotWindow(windows, FIVE_HOUR_LABEL, snapshot.fiveHourPercent, data?.five_hour?.resets_at, now);
88428
+ pushSnapshotWindow(windows, WEEK_LABEL, snapshot.weekPercent, data?.seven_day?.resets_at, now);
88429
+ return windows;
88430
+ }
88431
+ function fromRawUtilization(data) {
88432
+ if (!data)
88433
+ return [];
88434
+ const windows = [];
88435
+ const fiveHour = normalizeUtilization(data.five_hour?.utilization);
88436
+ if (fiveHour != null)
88437
+ windows.push(`${FIVE_HOUR_LABEL} ${fiveHour}%`);
88438
+ const week = normalizeUtilization(data.seven_day?.utilization);
88439
+ if (week != null)
88440
+ windows.push(`${WEEK_LABEL} ${week}%`);
88441
+ return windows;
88442
+ }
88443
+ function quotaWindows(now = Date.now()) {
88444
+ const cache3 = readUsageCache();
88445
+ if (!cache3 || cache3.status !== "available")
88446
+ return [];
88447
+ if (!isUsageCacheFresh(cache3, RENDER_TTL_MS, now))
88448
+ return [];
88449
+ const snapshotWindows = fromSnapshot(cache3.snapshot, cache3.data, now);
88450
+ return snapshotWindows.length > 0 ? snapshotWindows : fromRawUtilization(cache3.data);
88451
+ }
88452
+
88453
+ // src/domains/statusline/components.ts
88454
+ import { homedir as homedir30 } from "node:os";
88455
+
88456
+ // src/domains/statusline/colors.ts
88457
+ init_help_colors();
88458
+ var COLOR_ENABLED = process.env.NO_COLOR === undefined;
88459
+ var RESET = "\x1B[0m";
88460
+ var CLEAR_INTENSITY = "\x1B[22m";
88461
+ var CLEAR_FOREGROUND = "\x1B[39m";
88462
+ var STABLE_PREFIX = `${CLEAR_INTENSITY}${CLEAR_FOREGROUND}`;
88463
+ var STABLE_SUFFIX = `${RESET}${CLEAR_INTENSITY}${CLEAR_FOREGROUND}`;
88464
+ var CODES = {
88465
+ dim: "\x1B[2m",
88466
+ red: "\x1B[31m",
88467
+ green: "\x1B[32m",
88468
+ yellow: "\x1B[33m",
88469
+ magenta: "\x1B[35m",
88470
+ cyan: "\x1B[36m",
88471
+ brightRed: "\x1B[91m",
88472
+ brightGreen: "\x1B[92m",
88473
+ brightYellow: "\x1B[93m",
88474
+ brightMagenta: "\x1B[95m",
88475
+ brightCyan: "\x1B[96m"
88476
+ };
88477
+ function paint(name2, text2) {
88478
+ if (!COLOR_ENABLED)
88479
+ return text2;
88480
+ const code = CODES[name2];
88481
+ return code ? `${STABLE_PREFIX}${code}${text2}${STABLE_SUFFIX}` : text2;
88482
+ }
88483
+ function percentColorName(percent) {
88484
+ if (percent >= 80)
88485
+ return "brightRed";
88486
+ if (percent >= 50)
88487
+ return "brightYellow";
88488
+ return "brightGreen";
88489
+ }
88490
+ var BAR_GLYPHS = {
88491
+ geometric: { filled: "▰", empty: "▱" },
88492
+ block: { filled: "█", empty: "░" }
88493
+ };
88494
+ function progressBar2(percent, width = 10, style = "geometric", color) {
88495
+ if (width <= 0)
88496
+ return "";
88497
+ const { filled: fg, empty: bg } = BAR_GLYPHS[style];
88498
+ const clamped = Math.max(0, Math.min(100, percent));
88499
+ const filled = Math.round(clamped / 100 * width);
88500
+ const empty = width - filled;
88501
+ if (!COLOR_ENABLED)
88502
+ return fg.repeat(filled) + bg.repeat(empty);
88503
+ const filledColor = color && CODES[color] || CODES[percentColorName(percent)];
88504
+ return `${STABLE_PREFIX}${filledColor}${fg.repeat(filled)}${STABLE_PREFIX}${CODES.dim}${bg.repeat(empty)}${STABLE_SUFFIX}`;
88505
+ }
88506
+
88507
+ // src/domains/statusline/sanitize.ts
88508
+ var ANSI_SEQUENCE = /\x1b\[[0-9;?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[@-Z\\-_]/g;
88509
+ var CONTROL_CHARS = /[\x00-\x1f\x7f-\x9f]/g;
88510
+ function sanitizeField(value) {
88511
+ if (typeof value !== "string")
88512
+ return "";
88513
+ return value.replace(ANSI_SEQUENCE, "").replace(CONTROL_CHARS, "");
88514
+ }
88515
+
88516
+ // src/domains/statusline/activity-renderers.ts
88517
+ var MAX_AGENT_ROWS = 4;
88518
+ var TODO_TRUNCATION = 50;
88519
+ var DETAIL_LIMIT = 50;
88520
+ var NEXT_LIMIT = 40;
88521
+ function orderAgents(agents) {
88522
+ const rank = (a3) => a3.status === "running" ? 0 : 1;
88523
+ return [...agents].sort((a3, b4) => rank(a3) - rank(b4) || safeGetTime(a3.startTime) - safeGetTime(b4.startTime));
88524
+ }
88525
+ function collapseAgents(ordered) {
88526
+ const groups = [];
88527
+ for (const agent of ordered) {
88528
+ const type = sanitizeField(agent.type) || "agent";
88529
+ const previous = groups[groups.length - 1];
88530
+ if (previous && previous.type === type && previous.status === agent.status) {
88531
+ previous.count++;
88532
+ } else {
88533
+ groups.push({ type, status: agent.status, count: 1 });
88534
+ }
88535
+ }
88536
+ return groups;
88537
+ }
88538
+ function renderDetailLine(ordered) {
88539
+ const running = ordered.find((a3) => a3.status === "running");
88540
+ const completed = ordered.filter((a3) => a3.status === "completed");
88541
+ const agent = running ?? completed[completed.length - 1];
88542
+ if (!agent || !agent.description)
88543
+ return null;
88544
+ let desc = sanitizeField(agent.description);
88545
+ if (!desc)
88546
+ return null;
88547
+ if (desc.length > DETAIL_LIMIT)
88548
+ desc = `${desc.slice(0, DETAIL_LIMIT - 3)}...`;
88549
+ const tone = agent.status === "running" ? "yellow" : "dim";
88550
+ const elapsed = formatElapsed(agent.startTime, agent.endTime);
88551
+ return ` ${paint(tone, `▸ ${desc}`)} ${paint("dim", `(${elapsed})`)}`;
88552
+ }
88553
+ function renderAgentLines(agents, maxRows) {
88554
+ if (agents.length === 0)
88555
+ return [];
88556
+ const ordered = orderAgents(agents);
88557
+ const groups = collapseAgents(ordered).slice(-Math.max(1, maxRows));
88558
+ const rendered = groups.map((g3) => {
88559
+ const tone = g3.status === "running" ? "yellow" : "dim";
88560
+ const icon = g3.status === "running" ? "●" : "○";
88561
+ const suffix = g3.count > 1 ? `×${g3.count}` : "";
88562
+ return paint(tone, `${icon} ${g3.type}${suffix}`);
88563
+ });
88564
+ let summary = rendered.join(" → ");
88565
+ const completedCount = ordered.filter((a3) => a3.status === "completed").length;
88566
+ if (completedCount > 2)
88567
+ summary += paint("dim", ` (${completedCount} done)`);
88568
+ const lines = [summary];
88569
+ const detail = renderDetailLine(ordered);
88570
+ if (detail)
88571
+ lines.push(detail);
88572
+ return lines;
88573
+ }
88574
+ function renderTodoLine(todos, truncation) {
88575
+ if (todos.length === 0)
88576
+ return null;
88577
+ const limit = Math.max(10, truncation);
88578
+ const done = todos.filter((t) => t.status === "completed").length;
88579
+ const pending = todos.filter((t) => t.status === "pending").length;
88580
+ const active = todos.find((t) => t.status === "in_progress");
88581
+ if (active) {
88582
+ let text2 = sanitizeField(active.activeForm || active.content);
88583
+ if (!text2)
88584
+ return null;
88585
+ if (text2.length > limit)
88586
+ text2 = `${text2.slice(0, limit - 3)}...`;
88587
+ return paint("yellow", `▸ ${text2} (${done} done, ${pending} pending)`);
88588
+ }
88589
+ if (done === todos.length) {
88590
+ return paint("green", `✓ All ${todos.length} todos complete`);
88591
+ }
88592
+ if (pending > 0) {
88593
+ const next = todos.find((t) => t.status === "pending");
88594
+ let text2 = sanitizeField(next?.content || "Next task");
88595
+ if (text2.length > NEXT_LIMIT)
88596
+ text2 = `${text2.slice(0, NEXT_LIMIT - 3)}...`;
88597
+ return paint("dim", `○ Next: ${text2} (${done} done, ${pending} pending)`);
88598
+ }
88599
+ return null;
88600
+ }
88601
+ function renderActivityLines(snapshot, opts) {
88602
+ if (!snapshot)
88603
+ return [];
88604
+ const lines = renderAgentLines(snapshot.agents, opts?.maxAgentRows ?? MAX_AGENT_ROWS);
88605
+ const todoLine = renderTodoLine(snapshot.todos, opts?.todoTruncation ?? TODO_TRUNCATION);
88606
+ if (todoLine)
88607
+ lines.push(todoLine);
88608
+ return lines;
88609
+ }
88610
+
88611
+ // src/domains/statusline/components.ts
88612
+ function normalizeVersion2(raw) {
88613
+ const v3 = sanitizeField(raw ?? "").trim();
88614
+ if (!v3 || v3.toLowerCase() === "unknown")
88615
+ return null;
88616
+ return `v${v3.replace(/^v/i, "")}`;
88617
+ }
88618
+ function renderBrand(data, s3) {
88619
+ const cli = s3.showCliVersion ? normalizeVersion2(data.versions.cli) : null;
88620
+ let takumi = paint(s3.color, "Takumi");
88621
+ if (cli)
88622
+ takumi += ` ${paint(s3.versionColor, cli)}`;
88623
+ const pieces = [takumi];
88624
+ const core = s3.showCoreVersion ? normalizeVersion2(data.versions.core) : null;
88625
+ if (core)
88626
+ pieces.push(`${paint(s3.color, "core")} ${paint(s3.versionColor, core)}`);
88627
+ const icon = s3.icon ? `${paint(s3.color, s3.icon)} ` : "";
88628
+ return `${icon}${pieces.join(paint(s3.color, " · "))}`;
88629
+ }
88630
+ function renderModel(data, s3) {
88631
+ return paint(s3.color, sanitizeField(data.modelName) || "Claude");
88632
+ }
88633
+ function renderContext(data, s3) {
88634
+ const pct = data.contextPercent;
88635
+ if (!(pct > 0))
88636
+ return null;
88637
+ const color = pct >= s3.thresholds.high ? s3.colors.high : pct >= s3.thresholds.mid ? s3.colors.mid : s3.colors.low;
88638
+ const bar = progressBar2(pct, s3.barWidth, s3.barStyle, color);
88639
+ const pctText = s3.showPercent ? paint(color, `${pct}%`) : "";
88640
+ const parts = [bar, pctText].filter(Boolean);
88641
+ return parts.length ? parts.join(" ") : null;
88642
+ }
88643
+ var WINDOW_ALIASES = {
88644
+ "5h": "5h",
88645
+ "5hour": "5h",
88646
+ week: "wk",
88647
+ weekly: "wk",
88648
+ wk: "wk"
88649
+ };
88650
+ function renderQuotas(data, s3) {
88651
+ if (data.usageWindows.length === 0)
88652
+ return null;
88653
+ const allow = new Set(s3.windows.map((w4) => WINDOW_ALIASES[w4.toLowerCase()] ?? w4.toLowerCase()));
88654
+ const parts = [];
88655
+ for (const windowText of data.usageWindows) {
88656
+ const clean = sanitizeField(windowText);
88657
+ const match = clean.match(/^(\w+)\s+(\d+)%(.*)$/);
88658
+ if (!match) {
88659
+ parts.push(paint("dim", clean));
88660
+ continue;
88661
+ }
88662
+ const [, label, pctStr, rest] = match;
88663
+ if (allow.size > 0 && !allow.has(label.toLowerCase()))
88664
+ continue;
88665
+ const pct = Number.parseInt(pctStr, 10);
88666
+ const color = pct >= 85 ? "brightRed" : "brightGreen";
88667
+ const value = paint(color, `${pct}%${s3.showCountdown ? rest : ""}`);
88668
+ parts.push(s3.barWidth > 0 ? `${label} ${progressBar2(pct, s3.barWidth, "geometric", color)} ${value}` : `${paint("dim", label)} ${value}`);
88669
+ }
88670
+ return parts.length ? `${s3.icon} ${parts.join(" ")}` : null;
88671
+ }
88672
+ function shortenLeadingDirs(path11, keepFull) {
88673
+ if (keepFull <= 0)
88674
+ return path11;
88675
+ const marker = path11.startsWith("~") ? "~" : "";
88676
+ const body = marker ? path11.slice(marker.length) : path11;
88677
+ const leadingSlash = body.startsWith("/");
88678
+ const segments = body.split("/").filter(Boolean);
88679
+ if (segments.length <= keepFull)
88680
+ return path11;
88681
+ const leadCount = segments.length - keepFull;
88682
+ const shortened = segments.map((seg, i) => i < leadCount ? Array.from(seg)[0] ?? seg : seg);
88683
+ const sep9 = marker || leadingSlash ? "/" : "";
88684
+ return `${marker}${sep9}${shortened.join("/")}`;
88685
+ }
88686
+ function renderDirectory(data, s3) {
88687
+ let path11 = data.cwd || process.cwd();
88688
+ if (s3.collapseHome) {
88689
+ const home6 = homedir30();
88690
+ if (home6 && path11.startsWith(home6))
88691
+ path11 = `~${path11.slice(home6.length)}`;
88692
+ }
88693
+ path11 = shortenLeadingDirs(path11, s3.truncationLength);
88694
+ return `${s3.icon} ${paint(s3.color, sanitizeField(path11))}`;
88695
+ }
88696
+ function renderGit(data, s3) {
88697
+ const git = data.git;
88698
+ if (!git || !git.branch)
88699
+ return null;
88700
+ let part = `${s3.icon} ${paint(s3.branchColor, sanitizeField(git.branch))}`;
88701
+ if (s3.showDirty) {
88702
+ const insertions = git.trackedInsertions + (s3.countUntracked ? git.untrackedInsertions : 0);
88703
+ const tokens = [];
88704
+ if (insertions > 0)
88705
+ tokens.push(paint("green", `+${insertions}`));
88706
+ if (git.deletions > 0)
88707
+ tokens.push(paint("red", `-${git.deletions}`));
88708
+ if (tokens.length > 0) {
88709
+ part += s3.dirtyInBrackets ? ` (${tokens.join(" ")})` : ` ${tokens.join(" ")}`;
88710
+ }
88711
+ }
88712
+ if (s3.showAheadBehind) {
88713
+ if (git.ahead > 0)
88714
+ part += ` ${paint("dim", `⇡${git.ahead}`)}`;
88715
+ if (git.behind > 0)
88716
+ part += ` ${paint("dim", `⇣${git.behind}`)}`;
88717
+ }
88718
+ return part;
88719
+ }
88720
+ function renderCost(data, s3) {
88721
+ const cost = data.costUsd;
88722
+ if (cost == null)
88723
+ return null;
88724
+ if (s3.hideZero && !(cost > 0))
88725
+ return null;
88726
+ return `${s3.icon} ${paint("dim", `$${cost.toFixed(4)}`)}`;
88727
+ }
88728
+ function renderActivity(data, s3) {
88729
+ return renderActivityLines(data.activity, {
88730
+ maxAgentRows: s3.maxAgentRows,
88731
+ todoTruncation: s3.todoTruncation
88732
+ });
88733
+ }
88734
+
88735
+ // src/domains/statusline/renderer.ts
88736
+ function renderInline(name2, data, settings) {
88737
+ switch (name2) {
88738
+ case "brand":
88739
+ return renderBrand(data, settings.brand);
88740
+ case "model":
88741
+ return renderModel(data, settings.model);
88742
+ case "context":
88743
+ return renderContext(data, settings.context);
88744
+ case "quotas":
88745
+ return renderQuotas(data, settings.quotas);
88746
+ case "directory":
88747
+ return renderDirectory(data, settings.directory);
88748
+ case "git":
88749
+ return renderGit(data, settings.git);
88750
+ case "cost":
88751
+ return renderCost(data, settings.cost);
88752
+ default:
88753
+ return null;
88754
+ }
88755
+ }
88756
+ function renderStatusline(data, settings) {
88757
+ const prompt = settings.prompt ?? "";
88758
+ const activityLines = prompt.includes("$activity") ? renderActivity(data, settings.activity) : [];
88759
+ const inlinePrompt = prompt.replace(/\$activity/g, "");
88760
+ const substituted = inlinePrompt.replace(/\$([a-z]+)/g, (_match, name2) => {
88761
+ return renderInline(name2, data, settings) ?? "";
88762
+ });
88763
+ const mainLine = substituted.replace(/[ \t]{2,}/g, " ").trim();
88764
+ const lines = [];
88765
+ if (mainLine)
88766
+ lines.push(mainLine);
88767
+ for (const line of activityLines) {
88768
+ if (line)
88769
+ lines.push(line);
88770
+ }
88771
+ return lines.join(`
88772
+ `);
88773
+ }
88774
+
88775
+ // src/domains/statusline/versions.ts
88776
+ import { join as join137 } from "node:path";
88777
+ async function resolveCoreVersion(cwd2) {
88778
+ try {
88779
+ const { readManifest: readManifest3 } = await Promise.resolve().then(() => (init_manifest(), exports_manifest));
88780
+ const meta = await readManifest3(join137(cwd2, ".claude"));
88781
+ if (!meta)
88782
+ return null;
88783
+ const kits = meta.kits;
88784
+ const version3 = kits?.core?.version ?? meta.version;
88785
+ return typeof version3 === "string" && version3.length > 0 ? version3 : null;
88786
+ } catch {
88787
+ return null;
88788
+ }
88789
+ }
88790
+
88791
+ // src/commands/statusline/statusline-command.ts
88792
+ init_takumi_constants();
88793
+ function writeDebug(enabled, context, err) {
88794
+ if (!enabled)
88795
+ return;
88796
+ try {
88797
+ ensureStatuslineCacheDir();
88798
+ const detail = err instanceof Error ? err.stack ?? err.message : String(err);
88799
+ appendFileSync3(getStatuslineCachePath("debug.log"), `[${new Date().toISOString()}] ${context}: ${detail}
88800
+ `, {
88801
+ mode: 384
88802
+ });
88803
+ } catch {}
88804
+ }
88805
+ function collapseHome(p2) {
88806
+ const home6 = homedir31();
88807
+ return home6 && p2.startsWith(home6) ? `~${p2.slice(home6.length)}` : p2;
88808
+ }
88809
+ function fallbackLine(cwd2) {
88810
+ const safe = sanitizeField(collapseHome(cwd2 || process.cwd() || "unknown")) || "unknown";
88811
+ return `\uD83D\uDCC1 ${safe}`;
88812
+ }
88813
+ async function runUsageCacheRefresh(debug) {
88814
+ try {
88815
+ const { refreshUsageCache: refreshUsageCache2 } = await Promise.resolve().then(() => (init_usage_limits_cache(), exports_usage_limits_cache));
88816
+ await refreshUsageCache2();
88817
+ } catch (err) {
88818
+ writeDebug(debug, "refresh-usage-cache", err);
88819
+ }
88820
+ process.exitCode = 0;
88821
+ }
88822
+ async function statuslineCommand(options2 = {}) {
88823
+ if (options2.refreshUsageCache) {
88824
+ await runUsageCacheRefresh(options2.debug);
88825
+ return;
88826
+ }
88827
+ let fallbackCwd = "";
88828
+ try {
88829
+ const raw = await readStdinJson();
88830
+ if (Object.keys(raw).length === 0) {
88831
+ process.stdout.write(`${fallbackLine(process.cwd())}
88832
+ `);
88833
+ process.exitCode = 0;
88834
+ return;
88835
+ }
88836
+ const payload = parseStatusPayload(raw);
88837
+ fallbackCwd = payload.cwd;
88838
+ const cwd2 = payload.cwd || process.cwd();
88839
+ const settings = await loadStatuslineSettings(cwd2);
88840
+ const billingMode = process.env.CLAUDE_BILLING_MODE || "api";
88841
+ const costUsd = billingMode === "api" ? payload.costUsd : null;
88842
+ const core = settings.brand.showCoreVersion ? await resolveCoreVersion(cwd2) : null;
88843
+ const data = {
88844
+ modelName: payload.modelName,
88845
+ cwd: cwd2,
88846
+ git: getGitSnapshot(cwd2),
88847
+ contextPercent: computeContextPercent(payload.contextWindow),
88848
+ costUsd,
88849
+ usageWindows: quotaWindows(),
88850
+ activity: readActivity(payload.sessionId)?.snapshot ?? null,
88851
+ versions: { cli: getCliVersion(), core }
88852
+ };
88853
+ process.stdout.write(`${renderStatusline(data, settings)}
88854
+ `);
88855
+ process.exitCode = 0;
88856
+ } catch (err) {
88857
+ writeDebug(options2.debug, "render", err);
88858
+ process.stdout.write(`${fallbackLine(fallbackCwd)}
88859
+ `);
88860
+ process.exitCode = 0;
88861
+ }
88862
+ }
87038
88863
  // src/commands/telemetry/telemetry-command.ts
87039
88864
  init_logger();
87040
88865
 
@@ -87042,24 +88867,24 @@ init_logger();
87042
88867
  init_logger();
87043
88868
 
87044
88869
  // src/commands/telemetry/shared.ts
87045
- import { existsSync as existsSync66, readFileSync as readFileSync26, readdirSync as readdirSync11 } from "node:fs";
87046
- import { homedir as homedir29 } from "node:os";
87047
- import { join as join134 } from "node:path";
88870
+ import { existsSync as existsSync68, readFileSync as readFileSync28, readdirSync as readdirSync12 } from "node:fs";
88871
+ import { homedir as homedir32 } from "node:os";
88872
+ import { join as join138 } from "node:path";
87048
88873
  init_token_store();
87049
88874
  init_manifest_path_resolver();
87050
88875
  init_takumi_constants();
87051
- var USER_CACHE_PATH = join134(homedir29(), ".claude", "sk-user.json");
87052
- var EVENT_BUFFER_DIR = join134(homedir29(), ".claude", "sk-events");
87053
- var RATE_STATE_PATH = join134(homedir29(), ".claude", "sk-rate-state.json");
87054
- var TAKUMI_MANIFEST_PATH = join134(homedir29(), ".claude", MANIFEST_FILENAME);
87055
- var LEGACY_METADATA_PATH = join134(homedir29(), ".claude", LEGACY_MANIFEST_FILENAME);
88876
+ var USER_CACHE_PATH = join138(homedir32(), ".claude", "sk-user.json");
88877
+ var EVENT_BUFFER_DIR = join138(homedir32(), ".claude", "sk-events");
88878
+ var RATE_STATE_PATH = join138(homedir32(), ".claude", "sk-rate-state.json");
88879
+ var TAKUMI_MANIFEST_PATH = join138(homedir32(), ".claude", MANIFEST_FILENAME);
88880
+ var LEGACY_METADATA_PATH = join138(homedir32(), ".claude", LEGACY_MANIFEST_FILENAME);
87056
88881
  var TELEMETRY_HOOK_FIELD = "hooks.telemetry";
87057
88882
  var TOKEN_PLACEHOLDER = "__INJECT_AT_RELEASE__";
87058
88883
  function readUserCache() {
87059
88884
  try {
87060
- if (!existsSync66(USER_CACHE_PATH))
88885
+ if (!existsSync68(USER_CACHE_PATH))
87061
88886
  return null;
87062
- const parsed = JSON.parse(readFileSync26(USER_CACHE_PATH, "utf8"));
88887
+ const parsed = JSON.parse(readFileSync28(USER_CACHE_PATH, "utf8"));
87063
88888
  if (!parsed || typeof parsed !== "object")
87064
88889
  return null;
87065
88890
  return parsed;
@@ -87069,9 +88894,9 @@ function readUserCache() {
87069
88894
  }
87070
88895
  function countBufferFiles() {
87071
88896
  try {
87072
- if (!existsSync66(EVENT_BUFFER_DIR))
88897
+ if (!existsSync68(EVENT_BUFFER_DIR))
87073
88898
  return 0;
87074
- return readdirSync11(EVENT_BUFFER_DIR).filter((f4) => f4.endsWith(".jsonl")).length;
88899
+ return readdirSync12(EVENT_BUFFER_DIR).filter((f4) => f4.endsWith(".jsonl")).length;
87075
88900
  } catch {
87076
88901
  return 0;
87077
88902
  }
@@ -87081,9 +88906,9 @@ function readTelemetryConfig() {
87081
88906
  const envToken = process.env.TAKUMI_TELEMETRY_TOKEN;
87082
88907
  let metadata = null;
87083
88908
  try {
87084
- const resolved = findManifestPathSync(join134(homedir29(), ".claude"));
88909
+ const resolved = findManifestPathSync(join138(homedir32(), ".claude"));
87085
88910
  if (resolved) {
87086
- metadata = JSON.parse(readFileSync26(resolved.path, "utf8"));
88911
+ metadata = JSON.parse(readFileSync28(resolved.path, "utf8"));
87087
88912
  }
87088
88913
  } catch {
87089
88914
  metadata = null;
@@ -87107,8 +88932,8 @@ function collectRuntimeContext() {
87107
88932
  cacheSource: cache3?.source === "gh" || cache3?.source === "manual" ? cache3.source : null,
87108
88933
  bufferFileCount: countBufferFiles(),
87109
88934
  bufferDir: EVENT_BUFFER_DIR,
87110
- rateStateExists: existsSync66(RATE_STATE_PATH),
87111
- userCacheExists: existsSync66(USER_CACHE_PATH),
88935
+ rateStateExists: existsSync68(RATE_STATE_PATH),
88936
+ userCacheExists: existsSync68(USER_CACHE_PATH),
87112
88937
  endpoint,
87113
88938
  tokenConfigured: Boolean(token)
87114
88939
  };
@@ -87258,8 +89083,8 @@ init_logger();
87258
89083
  init_safe_prompts();
87259
89084
  init_safe_spinner();
87260
89085
  var import_fs_extra39 = __toESM(require_lib(), 1);
87261
- import { readdirSync as readdirSync13, rmSync as rmSync9 } from "node:fs";
87262
- import { join as join136, resolve as resolve34, sep as sep9 } from "node:path";
89086
+ import { readdirSync as readdirSync14, rmSync as rmSync11 } from "node:fs";
89087
+ import { join as join140, resolve as resolve34, sep as sep9 } from "node:path";
87263
89088
 
87264
89089
  // src/commands/uninstall/analysis-handler.ts
87265
89090
  init_metadata_migration();
@@ -87269,13 +89094,13 @@ init_logger();
87269
89094
  init_safe_prompts();
87270
89095
  init_takumi_constants();
87271
89096
  var import_picocolors28 = __toESM(require_picocolors(), 1);
87272
- import { existsSync as existsSync67, readdirSync as readdirSync12, rmSync as rmSync8 } from "node:fs";
87273
- import { dirname as dirname43, join as join135 } from "node:path";
89097
+ import { existsSync as existsSync69, readdirSync as readdirSync13, rmSync as rmSync10 } from "node:fs";
89098
+ import { dirname as dirname43, join as join139 } from "node:path";
87274
89099
  function listPresentManifestNames(installPath) {
87275
89100
  const present = [];
87276
- if (existsSync67(getManifestPath(installPath)))
89101
+ if (existsSync69(getManifestPath(installPath)))
87277
89102
  present.push(MANIFEST_FILENAME);
87278
- if (existsSync67(getLegacyManifestPath(installPath)))
89103
+ if (existsSync69(getLegacyManifestPath(installPath)))
87279
89104
  present.push(LEGACY_MANIFEST_FILENAME);
87280
89105
  return present;
87281
89106
  }
@@ -87296,9 +89121,9 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
87296
89121
  let currentDir = dirname43(filePath);
87297
89122
  while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
87298
89123
  try {
87299
- const entries = readdirSync12(currentDir);
89124
+ const entries = readdirSync13(currentDir);
87300
89125
  if (entries.length === 0) {
87301
- rmSync8(currentDir, { recursive: true });
89126
+ rmSync10(currentDir, { recursive: true });
87302
89127
  cleaned++;
87303
89128
  logger.debug(`Removed empty directory: ${currentDir}`);
87304
89129
  currentDir = dirname43(currentDir);
@@ -87323,7 +89148,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
87323
89148
  if (uninstallManifest.isMultiKit && kit && metadata?.kits?.[kit]) {
87324
89149
  const kitFiles = metadata.kits[kit].files || [];
87325
89150
  for (const trackedFile of kitFiles) {
87326
- const filePath = join135(installation.path, trackedFile.path);
89151
+ const filePath = join139(installation.path, trackedFile.path);
87327
89152
  if (uninstallManifest.filesToPreserve.includes(trackedFile.path)) {
87328
89153
  result.toPreserve.push({ path: trackedFile.path, reason: "shared with other kit" });
87329
89154
  continue;
@@ -87355,7 +89180,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
87355
89180
  return result;
87356
89181
  }
87357
89182
  for (const trackedFile of allTrackedFiles) {
87358
- const filePath = join135(installation.path, trackedFile.path);
89183
+ const filePath = join139(installation.path, trackedFile.path);
87359
89184
  const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
87360
89185
  if (!ownershipResult.exists)
87361
89186
  continue;
@@ -87454,7 +89279,7 @@ async function removeInstallations(installations, options2) {
87454
89279
  let removedCount = 0;
87455
89280
  let cleanedDirs = 0;
87456
89281
  for (const item of analysis.toDelete) {
87457
- const filePath = join136(installation.path, item.path);
89282
+ const filePath = join140(installation.path, item.path);
87458
89283
  if (!await import_fs_extra39.pathExists(filePath))
87459
89284
  continue;
87460
89285
  if (!await isPathSafeToRemove(filePath, installation.path)) {
@@ -87473,9 +89298,9 @@ async function removeInstallations(installations, options2) {
87473
89298
  await ManifestWriter.removeKitFromManifest(installation.path, options2.kit);
87474
89299
  }
87475
89300
  try {
87476
- const remaining = readdirSync13(installation.path);
89301
+ const remaining = readdirSync14(installation.path);
87477
89302
  if (remaining.length === 0) {
87478
- rmSync9(installation.path, { recursive: true });
89303
+ rmSync11(installation.path, { recursive: true });
87479
89304
  logger.debug(`Removed empty installation directory: ${installation.path}`);
87480
89305
  }
87481
89306
  } catch {}
@@ -87656,7 +89481,7 @@ ${import_picocolors29.default.yellow("User modifications will be permanently del
87656
89481
  // src/commands/update-cli.ts
87657
89482
  init_takumi_config_manager();
87658
89483
  init_npm_registry();
87659
- import { exec as exec8, spawn as spawn4 } from "node:child_process";
89484
+ import { exec as exec8, spawn as spawn5 } from "node:child_process";
87660
89485
  import { promisify as promisify14 } from "node:util";
87661
89486
  init_metadata_migration();
87662
89487
  init_version_utils();
@@ -87885,7 +89710,7 @@ async function promptKitUpdate(beta, yes, deps) {
87885
89710
  const displayCmd = `tkm ${args.join(" ")}`;
87886
89711
  logger.info(`Running: ${displayCmd}`);
87887
89712
  const spawnFn = deps?.spawnInitFn ?? ((spawnArgs) => new Promise((resolve35) => {
87888
- const child = spawn4("tkm", spawnArgs, { stdio: "inherit", shell: true });
89713
+ const child = spawn5("tkm", spawnArgs, { stdio: "inherit", shell: true });
87889
89714
  child.on("close", (code) => resolve35(code ?? 1));
87890
89715
  child.on("error", (err) => {
87891
89716
  logger.verbose(`Failed to spawn tkm init: ${err.message}`);
@@ -88274,6 +90099,12 @@ function registerCommands(cli) {
88274
90099
  debug: options2.debug
88275
90100
  });
88276
90101
  });
90102
+ cli.command("statusline", "Render the Takumi statusline from a piped status JSON (agent-invoked)").option("--refresh-usage-cache", "Internal: run the detached usage-cache refresh").option("--debug", "Log swallowed errors to <cache>/statusline/debug.log").action(async (options2 = {}) => {
90103
+ await statuslineCommand({
90104
+ refreshUsageCache: options2.refreshUsageCache,
90105
+ debug: options2.debug
90106
+ });
90107
+ });
88277
90108
  cli.command("plan [action] [target]", "Plan management: parse, validate, status, kanban, create, check, uncheck, add-phase").option("--json", "Output in JSON format").option("--strict", "Strict validation mode").option("--title <title>", "Plan title (for create)").option("--phases <phases>", "Comma-separated phase names (for create)").option("--dir <dir>", "Plan directory (for create)").option("--priority <priority>", "Priority: P1, P2, P3 (for create)").option("--issue <issue>", "GitHub issue number (for create)").option("--after <after>", "Insert after phase ID (for add-phase)").option("--start", "Mark as in-progress instead of completed (for check)").action(async (action, target, options2) => {
88278
90109
  await planCommand(action, target, options2);
88279
90110
  });
@@ -88325,8 +90156,8 @@ init_version_checker();
88325
90156
  init_manifest_path_resolver();
88326
90157
  init_logger();
88327
90158
  init_types2();
88328
- import { readFileSync as readFileSync27 } from "node:fs";
88329
- import { join as join137 } from "node:path";
90159
+ import { readFileSync as readFileSync29 } from "node:fs";
90160
+ import { join as join141 } from "node:path";
88330
90161
  var PROVIDER_LOCAL_SUBDIRS = {
88331
90162
  "claude-code": ".claude",
88332
90163
  codex: ".codex"
@@ -88381,7 +90212,7 @@ async function displayVersion() {
88381
90212
  const localSubdir = PROVIDER_LOCAL_SUBDIRS[provider];
88382
90213
  if (!localSubdir)
88383
90214
  continue;
88384
- const localRoot = join137(process.cwd(), localSubdir);
90215
+ const localRoot = join141(process.cwd(), localSubdir);
88385
90216
  if (localRoot === inst.globalRoot())
88386
90217
  continue;
88387
90218
  const resolved = findManifestPathSync(localRoot);
@@ -88391,7 +90222,7 @@ async function displayVersion() {
88391
90222
  }
88392
90223
  for (const { provider, path: metaPath } of localChecks) {
88393
90224
  try {
88394
- const rawMetadata = JSON.parse(readFileSync27(metaPath, "utf-8"));
90225
+ const rawMetadata = JSON.parse(readFileSync29(metaPath, "utf-8"));
88395
90226
  const metadata = MetadataSchema.parse(rawMetadata);
88396
90227
  const kitsDisplay = formatInstalledKits(metadata);
88397
90228
  if (kitsDisplay) {
@@ -88411,7 +90242,7 @@ async function displayVersion() {
88411
90242
  const resolved = findManifestPathSync(installPath);
88412
90243
  if (resolved) {
88413
90244
  try {
88414
- const rawMetadata = JSON.parse(readFileSync27(resolved.path, "utf-8"));
90245
+ const rawMetadata = JSON.parse(readFileSync29(resolved.path, "utf-8"));
88415
90246
  const metadata = MetadataSchema.parse(rawMetadata);
88416
90247
  const kitsDisplay = formatInstalledKits(metadata);
88417
90248
  if (kitsDisplay) {
@@ -88566,8 +90397,8 @@ class Logger2 {
88566
90397
  process.exit(1);
88567
90398
  });
88568
90399
  }
88569
- sanitize(text) {
88570
- return text.replace(/ghp_[a-zA-Z0-9]{36}/g, "ghp_***").replace(/github_pat_[a-zA-Z0-9_]{82}/g, "github_pat_***").replace(/gho_[a-zA-Z0-9]{36}/g, "gho_***").replace(/ghu_[a-zA-Z0-9]{36}/g, "ghu_***").replace(/ghs_[a-zA-Z0-9]{36}/g, "ghs_***").replace(/ghr_[a-zA-Z0-9]{36}/g, "ghr_***").replace(/Bearer [a-zA-Z0-9_-]+/g, "Bearer ***").replace(/token=[a-zA-Z0-9_-]+/g, "token=***");
90400
+ sanitize(text2) {
90401
+ return text2.replace(/ghp_[a-zA-Z0-9]{36}/g, "ghp_***").replace(/github_pat_[a-zA-Z0-9_]{82}/g, "github_pat_***").replace(/gho_[a-zA-Z0-9]{36}/g, "gho_***").replace(/ghu_[a-zA-Z0-9]{36}/g, "ghu_***").replace(/ghs_[a-zA-Z0-9]{36}/g, "ghs_***").replace(/ghr_[a-zA-Z0-9]{36}/g, "ghr_***").replace(/Bearer [a-zA-Z0-9_-]+/g, "Bearer ***").replace(/token=[a-zA-Z0-9_-]+/g, "token=***");
88571
90402
  }
88572
90403
  getTimestamp() {
88573
90404
  return new Date().toISOString();
@@ -88793,7 +90624,7 @@ var output2 = new OutputManager2;
88793
90624
  // src/shared/temp-cleanup.ts
88794
90625
  init_logger();
88795
90626
  var import_fs_extra41 = __toESM(require_lib(), 1);
88796
- import { rmSync as rmSync10 } from "node:fs";
90627
+ import { rmSync as rmSync12 } from "node:fs";
88797
90628
  var tempDirs2 = new Set;
88798
90629
  async function cleanup() {
88799
90630
  if (tempDirs2.size === 0)
@@ -88814,7 +90645,7 @@ function cleanupSync() {
88814
90645
  return;
88815
90646
  for (const dir of tempDirs2) {
88816
90647
  try {
88817
- rmSync10(dir, { recursive: true, force: true });
90648
+ rmSync12(dir, { recursive: true, force: true });
88818
90649
  } catch {}
88819
90650
  }
88820
90651
  tempDirs2.clear();