@hasna/instructions 0.5.3 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -1290,8 +1290,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1290
1290
  args = args.slice();
1291
1291
  let launchWithNode = false;
1292
1292
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1293
- function findFile(baseDir, baseName) {
1294
- const localBin = path.resolve(baseDir, baseName);
1293
+ function findFile(baseDir2, baseName) {
1294
+ const localBin = path.resolve(baseDir2, baseName);
1295
1295
  if (fs.existsSync(localBin))
1296
1296
  return localBin;
1297
1297
  if (sourceExt.includes(path.extname(baseName)))
@@ -2160,19 +2160,122 @@ var init_retired_storage_mode = __esm(() => {
2160
2160
  ];
2161
2161
  });
2162
2162
 
2163
+ // ../../node_modules/.bun/@hasna+paths@0.1.0/node_modules/@hasna/paths/dist/index.js
2164
+ import { homedir as homedir3 } from "os";
2165
+ import { join as join4 } from "path";
2166
+ function assertApp2(app) {
2167
+ if (typeof app !== "string" || app.length === 0) {
2168
+ throw new TypeError("paths: app must be a non-empty string");
2169
+ }
2170
+ if (!APP_SLUG_RE2.test(app)) {
2171
+ throw new TypeError(`paths: invalid app slug "${app}" \u2014 expected lowercase kebab-case ([a-z0-9]+(-[a-z0-9]+)*)`);
2172
+ }
2173
+ }
2174
+ function envOf2(options) {
2175
+ return options.env ?? process.env;
2176
+ }
2177
+ function envValue2(options, kind) {
2178
+ const value = envOf2(options)[KIND_ENV2[kind]];
2179
+ return typeof value === "string" && value.length > 0 ? value : undefined;
2180
+ }
2181
+ function isMacOS2(platform) {
2182
+ return platform === "darwin";
2183
+ }
2184
+ function baseDir2(kind, options) {
2185
+ const override = envValue2(options, kind);
2186
+ if (override)
2187
+ return override;
2188
+ const home = options.home ?? homedir3();
2189
+ const platform = options.platform ?? process.platform;
2190
+ if (isMacOS2(platform)) {
2191
+ switch (kind) {
2192
+ case "config":
2193
+ case "data":
2194
+ return join4(home, "Library", "Application Support", "Hasna");
2195
+ case "cache":
2196
+ return join4(home, "Library", "Caches", "Hasna");
2197
+ case "state":
2198
+ return join4(home, "Library", "Logs", "Hasna");
2199
+ }
2200
+ }
2201
+ switch (kind) {
2202
+ case "config":
2203
+ return join4(home, ".config", "hasna");
2204
+ case "data":
2205
+ return join4(home, ".local", "share", "hasna");
2206
+ case "state":
2207
+ return join4(home, ".local", "state", "hasna");
2208
+ case "cache":
2209
+ return join4(home, ".cache", "hasna");
2210
+ }
2211
+ }
2212
+ function resolvePath2(kind, options) {
2213
+ assertApp2(options.app);
2214
+ const appSegment = options.internal === true ? join4("internal", options.app) : options.app;
2215
+ return join4(baseDir2(kind, options), appSegment);
2216
+ }
2217
+ function configDir(options) {
2218
+ return resolvePath2("config", options);
2219
+ }
2220
+ var KIND_ENV2, APP_SLUG_RE2;
2221
+ var init_dist = __esm(() => {
2222
+ KIND_ENV2 = {
2223
+ config: "HASNA_CONFIG_HOME",
2224
+ data: "HASNA_DATA_HOME",
2225
+ state: "HASNA_STATE_HOME",
2226
+ cache: "HASNA_CACHE_HOME"
2227
+ };
2228
+ APP_SLUG_RE2 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
2229
+ });
2230
+
2231
+ // src/lib/app-home.ts
2232
+ import { existsSync as existsSync3 } from "fs";
2233
+ import { homedir as homedir5 } from "os";
2234
+ import { join as join6, resolve as resolve2 } from "path";
2235
+ function homeDir(env = process.env) {
2236
+ return env["HOME"] || env["USERPROFILE"] || homedir5();
2237
+ }
2238
+ function legacyStoreHome(env = process.env) {
2239
+ return resolve2(join6(homeDir(env), ".hasna", "instructions"));
2240
+ }
2241
+ function resolverStoreHome(env = process.env) {
2242
+ return configDir({ app: "configs", env, home: env.HOME || env.USERPROFILE || homedir5() });
2243
+ }
2244
+ function adoptResolverStoreHome(resolved, env = process.env) {
2245
+ const override = env.HASNA_CONFIG_HOME;
2246
+ if (typeof override === "string" && override.trim().length > 0)
2247
+ return true;
2248
+ return existsSync3(join6(resolved, "instructions.db"));
2249
+ }
2250
+ function exactStoreHome(env = process.env) {
2251
+ const v = env[HASNA_CONFIGS_HOME_ENV];
2252
+ return v && v.trim() ? v.trim() : undefined;
2253
+ }
2254
+ function getConfigsStoreHome(env = process.env) {
2255
+ const exact = exactStoreHome(env);
2256
+ if (exact)
2257
+ return resolve2(exact);
2258
+ const resolved = resolverStoreHome(env);
2259
+ return adoptResolverStoreHome(resolved, env) ? resolve2(resolved) : legacyStoreHome(env);
2260
+ }
2261
+ var HASNA_CONFIGS_HOME_ENV = "HASNA_CONFIGS_HOME";
2262
+ var init_app_home = __esm(() => {
2263
+ init_dist();
2264
+ });
2265
+
2163
2266
  // src/lib/raw-store-root.ts
2164
- import { homedir as homedir2 } from "os";
2165
- import { join as join2, resolve } from "path";
2166
- function getRawStoreRoot() {
2167
- return resolve(process.env[RAW_STORE_ROOT_ENV] || join2(process.env["HOME"] || homedir2(), ".hasna", "instructions"));
2267
+ import { resolve as resolve3 } from "path";
2268
+ function getRawStoreRoot(env = process.env) {
2269
+ return resolve3(getConfigsStoreHome(env));
2168
2270
  }
2169
- var RAW_STORE_ROOT_ENV = "HASNA_CONFIGS_HOME";
2170
- var init_raw_store_root = () => {};
2271
+ var init_raw_store_root = __esm(() => {
2272
+ init_app_home();
2273
+ });
2171
2274
 
2172
2275
  // src/db/database.ts
2173
2276
  import { Database } from "bun:sqlite";
2174
- import { existsSync as existsSync2, mkdirSync, rmSync } from "fs";
2175
- import { join as join3 } from "path";
2277
+ import { existsSync as existsSync5, mkdirSync, rmSync } from "fs";
2278
+ import { join as join7 } from "path";
2176
2279
  import { randomUUID as randomUUID3 } from "crypto";
2177
2280
  function getDbPath() {
2178
2281
  if (process.env["HASNA_INSTRUCTIONS_DB_PATH"]) {
@@ -2180,7 +2283,7 @@ function getDbPath() {
2180
2283
  }
2181
2284
  const dir = getRawStoreRoot();
2182
2285
  mkdirSync(dir, { recursive: true });
2183
- return join3(dir, "instructions.db");
2286
+ return join7(dir, "instructions.db");
2184
2287
  }
2185
2288
  function uuid() {
2186
2289
  return randomUUID3();
@@ -2221,7 +2324,7 @@ function resetLocalDatabase() {
2221
2324
  if (dbPath === ":memory:")
2222
2325
  return;
2223
2326
  for (const p of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
2224
- if (existsSync2(p))
2327
+ if (existsSync5(p))
2225
2328
  rmSync(p);
2226
2329
  }
2227
2330
  }
@@ -2658,9 +2761,9 @@ var init_template = __esm(() => {
2658
2761
  });
2659
2762
 
2660
2763
  // src/lib/machine.ts
2661
- import { arch as currentArch, homedir as homedir3, hostname as currentHostname, type as currentOsType } from "os";
2662
- import { existsSync as existsSync3 } from "fs";
2663
- import { join as join4 } from "path";
2764
+ import { arch as currentArch, homedir as homedir6, hostname as currentHostname, type as currentOsType } from "os";
2765
+ import { existsSync as existsSync6 } from "fs";
2766
+ import { join as join8 } from "path";
2664
2767
  function normalizeOsFamily(os) {
2665
2768
  const value = (os ?? "").trim().toLowerCase();
2666
2769
  if (value === "darwin" || value === "macos" || value === "mac" || value === "osx")
@@ -2672,11 +2775,11 @@ function normalizeOsFamily(os) {
2672
2775
  return value || "unknown";
2673
2776
  }
2674
2777
  function detectMachineContext(overrides = {}) {
2675
- const homeDir = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir3();
2778
+ const homeDir2 = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir6();
2676
2779
  const os = overrides.os ?? currentOsType();
2677
2780
  const osFamily = normalizeOsFamily(os);
2678
- const bunBinDir = overrides.bun_bin_dir ?? join4(homeDir, ".bun", "bin");
2679
- const defaultBunPath = osFamily === "macos" && existsSync3(BREW_BUN_PATH) ? BREW_BUN_PATH : join4(bunBinDir, "bun");
2781
+ const bunBinDir = overrides.bun_bin_dir ?? join8(homeDir2, ".bun", "bin");
2782
+ const defaultBunPath = osFamily === "macos" && existsSync6(BREW_BUN_PATH) ? BREW_BUN_PATH : join8(bunBinDir, "bun");
2680
2783
  return {
2681
2784
  id: "current-machine",
2682
2785
  hostname: overrides.hostname ?? currentHostname(),
@@ -2685,11 +2788,11 @@ function detectMachineContext(overrides = {}) {
2685
2788
  last_applied_at: null,
2686
2789
  created_at: "",
2687
2790
  os_family: osFamily,
2688
- home_dir: homeDir,
2689
- workspace_root: overrides.workspace_root ?? join4(homeDir, osFamily === "macos" ? "Workspace" : "workspace"),
2791
+ home_dir: homeDir2,
2792
+ workspace_root: overrides.workspace_root ?? join8(homeDir2, osFamily === "macos" ? "Workspace" : "workspace"),
2690
2793
  bun_bin_dir: bunBinDir,
2691
2794
  bun_path: overrides.bun_path ?? defaultBunPath,
2692
- path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join4("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
2795
+ path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join8("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
2693
2796
  };
2694
2797
  }
2695
2798
  function machineContextToVariables(machine) {
@@ -7324,7 +7427,7 @@ import { dlopen, FFIType } from "bun:ffi";
7324
7427
  import {
7325
7428
  closeSync,
7326
7429
  constants,
7327
- existsSync as existsSync4,
7430
+ existsSync as existsSync7,
7328
7431
  fstatSync,
7329
7432
  fsyncSync,
7330
7433
  lstatSync,
@@ -7337,7 +7440,7 @@ import {
7337
7440
  statSync,
7338
7441
  writeFileSync
7339
7442
  } from "fs";
7340
- import { basename, dirname, isAbsolute, join as join5, parse, relative, resolve as resolve2 } from "path";
7443
+ import { basename, dirname, isAbsolute, join as join9, parse, relative, resolve as resolve4 } from "path";
7341
7444
  function managedObservationMaxBytes(relativePath) {
7342
7445
  return SESSION_MANAGED_OUTPUT_PATHS.includes(relativePath) ? SESSION_MANAGED_OUTPUT_MAX_BYTES : FOREIGN_INPUT_MAX_BYTES;
7343
7446
  }
@@ -7417,7 +7520,7 @@ function planProjectContext(input) {
7417
7520
  const inlineMarkerOverhead = nativeImports ? 0 : Buffer.byteLength(buildManagedBlock(bundle, "", `
7418
7521
  `), "utf8");
7419
7522
  const generated = buildCanonicalFragment(bundle, status, ageSeconds, PROJECT_CONTEXT_MAX_RENDERED_BYTES - Math.max(320, inlineMarkerOverhead), PROJECT_CONTEXT_MAX_APPROX_TOKENS - Math.max(80, Math.ceil(inlineMarkerOverhead / 4)));
7420
- const previousTargetContent = existsSync4(paths.target) ? readUtf8RegularFile(paths.target, workspaceRoot, managedObservationMaxBytes(relativePosix(workspaceRoot, paths.target))) : null;
7523
+ const previousTargetContent = existsSync7(paths.target) ? readUtf8RegularFile(paths.target, workspaceRoot, managedObservationMaxBytes(relativePosix(workspaceRoot, paths.target))) : null;
7421
7524
  const markerParse = parseManagedBlock(previousTargetContent ?? "", input.force === true);
7422
7525
  if (markerParse.block && markerParse.block.id !== bundle.project.id) {
7423
7526
  throw new ProjectContextError("MANAGED_BLOCK_CONFLICT", "managed block belongs to a different project");
@@ -7468,7 +7571,7 @@ function composeProjectContextSessionRender(input) {
7468
7571
  return null;
7469
7572
  const { runtime, workspace_root: workspaceRoot, observed_hashes: observedHashes } = guard;
7470
7573
  const paths = runtimePaths(workspaceRoot, runtime);
7471
- if (!existsSync4(paths.manifest))
7574
+ if (!existsSync7(paths.manifest))
7472
7575
  return null;
7473
7576
  assertCodewithTargetIsConsumed(workspaceRoot, runtime);
7474
7577
  const manifest = readProjectContextManifest(paths.manifest, workspaceRoot);
@@ -7497,7 +7600,7 @@ function composeProjectContextSessionRender(input) {
7497
7600
  }
7498
7601
  const fragment = readUtf8RegularFile(paths.fragment, workspaceRoot, PROJECT_CONTEXT_MAX_RENDERED_BYTES);
7499
7602
  scanGeneratedContent(fragment);
7500
- if (!existsSync4(paths.target)) {
7603
+ if (!existsSync7(paths.target)) {
7501
7604
  throw new ProjectContextError("MANAGED_BLOCK_CONFLICT", "project-context provider target is missing while durable context is active");
7502
7605
  }
7503
7606
  const currentTarget = readUtf8RegularFile(paths.target, workspaceRoot, managedObservationMaxBytes(relativePosix(workspaceRoot, paths.target)));
@@ -7508,7 +7611,7 @@ function composeProjectContextSessionRender(input) {
7508
7611
  if (currentMarkers.block.id !== cache.project_id || currentMarkers.block.revision !== cache.revision || currentMarkers.block.hash !== cache.hash) {
7509
7612
  throw new ProjectContextError("MANAGED_BLOCK_CONFLICT", "project-context provider markers differ from the durable cache");
7510
7613
  }
7511
- const plannedIndexes = input.files.filter((file) => file.role === "index" && resolve2(file.path) === paths.target);
7614
+ const plannedIndexes = input.files.filter((file) => file.role === "index" && resolve4(file.path) === paths.target);
7512
7615
  if (plannedIndexes.length !== 1) {
7513
7616
  throw new ProjectContextError("PROJECT_CONTEXT_MANIFEST_INVALID", "session renderer does not own the selected project-context provider target");
7514
7617
  }
@@ -7566,7 +7669,7 @@ function withProjectContextSessionGuard(guard, action, options = {}) {
7566
7669
  verify();
7567
7670
  return action(null);
7568
7671
  }
7569
- const lockPath = resolve2(validated.workspace_root, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
7672
+ const lockPath = resolve4(validated.workspace_root, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
7570
7673
  const lock = acquireWorkspaceLock(validated.workspace_root, lockPath);
7571
7674
  try {
7572
7675
  verify();
@@ -7592,7 +7695,7 @@ function validateProjectContextSessionGuard(guard) {
7592
7695
  if (!isRecord(observed) || typeof observed.path !== "string") {
7593
7696
  throw new ProjectContextError("PROJECT_CONTEXT_SESSION_STALE", "session project-context guard contains malformed hash metadata");
7594
7697
  }
7595
- const path = resolve2(observed.path);
7698
+ const path = resolve4(observed.path);
7596
7699
  if (!allowedPaths.has(path) || observedPaths.has(path)) {
7597
7700
  throw new ProjectContextError("PROJECT_CONTEXT_SESSION_STALE", "session project-context guard contains an unexpected or duplicate path");
7598
7701
  }
@@ -7614,7 +7717,7 @@ function validateProjectContextSessionGuard(guard) {
7614
7717
  function applyProjectContext(options) {
7615
7718
  const workspaceRoot = assertSafeWorkspaceRoot(options.workspace_root);
7616
7719
  const now3 = options.now ?? new Date;
7617
- const lockPath = resolve2(workspaceRoot, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
7720
+ const lockPath = resolve4(workspaceRoot, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
7618
7721
  const lock = options.dry_run ? null : acquireWorkspaceLock(workspaceRoot, lockPath, options.test_hooks?.after_lock_open, options.test_hooks?.before_stale_lock_remove, options.test_hooks?.process_start_identity);
7619
7722
  try {
7620
7723
  const resolved = resolveBundleForApply(options, workspaceRoot, now3);
@@ -7761,7 +7864,7 @@ function resolveBundleForApply(options, workspaceRoot, now3) {
7761
7864
  if (!options.expected_project_id) {
7762
7865
  throw new ProjectContextError("PROJECT_CONTEXT_CACHE_ID_REQUIRED", "expected_project_id is required for stale-cache fallback");
7763
7866
  }
7764
- const cachePath = resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
7867
+ const cachePath = resolve4(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
7765
7868
  const cache = readProjectContextCache(cachePath, workspaceRoot);
7766
7869
  if (!cache)
7767
7870
  throw new ProjectContextError("PROJECT_CONTEXT_CACHE_MISSING", "no last-known-good project context cache exists");
@@ -7963,7 +8066,7 @@ function findLegacyCodewithWorkspaceSection(workspaceRoot, runtime, content, bun
7963
8066
  if (runtime !== "codewith" || !content)
7964
8067
  return null;
7965
8068
  const sessionManifestPath = runtimePaths(workspaceRoot, runtime).sessionManifest;
7966
- if (!existsSync4(sessionManifestPath))
8069
+ if (!existsSync7(sessionManifestPath))
7967
8070
  return null;
7968
8071
  const manifest = readSessionManifestRecord(sessionManifestPath, workspaceRoot);
7969
8072
  if (!manifest || manifest["schema"] !== SESSION_RENDER_SCHEMA) {
@@ -8014,7 +8117,7 @@ function assertRevisionOrdering(plan, force) {
8014
8117
  const manifest = readProjectContextManifest(plan.manifest_path, plan.workspace_root);
8015
8118
  if (manifest) {
8016
8119
  const manifestHashHasRecoveryProof = manifest.projectContext.hash === plan.bundle.hash || metadataSnapshotMatchesManifest(plan, manifest);
8017
- const canonicalStateAlreadyInstalled = cache !== null && canonicalCacheHash === plan.bundle.hash && cache.project_id === plan.bundle.project.id && cache.revision === plan.bundle.revision && plan.marker !== null && plan.marker.id === plan.bundle.project.id && plan.marker.revision === plan.bundle.revision && plan.marker.hash === plan.bundle.hash && existsSync4(plan.fragment_path) && fragmentMatchesBundle(plan.fragment_path, plan.bundle, plan.workspace_root) && manifestHashHasRecoveryProof;
8120
+ const canonicalStateAlreadyInstalled = cache !== null && canonicalCacheHash === plan.bundle.hash && cache.project_id === plan.bundle.project.id && cache.revision === plan.bundle.revision && plan.marker !== null && plan.marker.id === plan.bundle.project.id && plan.marker.revision === plan.bundle.revision && plan.marker.hash === plan.bundle.hash && existsSync7(plan.fragment_path) && fragmentMatchesBundle(plan.fragment_path, plan.bundle, plan.workspace_root) && manifestHashHasRecoveryProof;
8018
8121
  observations.push({
8019
8122
  source: "manifest",
8020
8123
  id: manifest.projectContext.projectId,
@@ -8022,7 +8125,7 @@ function assertRevisionOrdering(plan, force) {
8022
8125
  hash: canonicalStateAlreadyInstalled && manifest.projectContext.projectId === plan.bundle.project.id && manifest.projectContext.revision === plan.bundle.revision ? plan.bundle.hash : normalizePersistedHash(manifest.projectContext.revision, manifest.projectContext.hash)
8023
8126
  });
8024
8127
  const fragmentEntry = manifest.files.find((file) => file.relativePath === PROJECT_CONTEXT_FRAGMENT_PATH);
8025
- if (fragmentEntry && existsSync4(plan.fragment_path)) {
8128
+ if (fragmentEntry && existsSync7(plan.fragment_path)) {
8026
8129
  const actual = currentFileHash(plan.fragment_path, plan.workspace_root);
8027
8130
  if (actual !== fragmentEntry.sha256 && !fragmentMatchesBundle(plan.fragment_path, plan.bundle, plan.workspace_root) && !force) {
8028
8131
  throw new ProjectContextError("MANAGED_BLOCK_CONFLICT", "canonical project-context fragment changed outside Instructions");
@@ -8117,9 +8220,9 @@ function buildManifest(plan, now3) {
8117
8220
  function buildSessionCompatibilityManifest(plan, now3) {
8118
8221
  const paths = runtimePaths(plan.workspace_root, plan.runtime);
8119
8222
  const tool = manifestTool(plan.runtime);
8120
- const targetHome = plan.runtime === "codewith" ? resolve2(plan.workspace_root, ".codewith") : plan.workspace_root;
8223
+ const targetHome = plan.runtime === "codewith" ? resolve4(plan.workspace_root, ".codewith") : plan.workspace_root;
8121
8224
  const targetRelativePath = sessionTargetRelativePath(plan.runtime);
8122
- const existing = existsSync4(paths.sessionManifest) ? readSessionManifestRecord(paths.sessionManifest, plan.workspace_root) : {
8225
+ const existing = existsSync7(paths.sessionManifest) ? readSessionManifestRecord(paths.sessionManifest, plan.workspace_root) : {
8123
8226
  schema: SESSION_RENDER_SCHEMA,
8124
8227
  tool,
8125
8228
  adapterMode: plan.native_imports ? "native-imports" : "flattened-markdown",
@@ -8139,7 +8242,7 @@ function buildSessionCompatibilityManifest(plan, now3) {
8139
8242
  throw new ProjectContextError("PROJECT_CONTEXT_MANIFEST_INVALID", "provider session manifest is malformed or incompatible");
8140
8243
  }
8141
8244
  const existingTargetHome = safeLegacyMetadataString(existing["targetHome"], null);
8142
- if (existingTargetHome !== null && resolve2(existingTargetHome) !== targetHome) {
8245
+ if (existingTargetHome !== null && resolve4(existingTargetHome) !== targetHome) {
8143
8246
  throw new ProjectContextError("PROJECT_CONTEXT_MANIFEST_INVALID", "provider session manifest targets a different workspace");
8144
8247
  }
8145
8248
  const sources = sanitizeLegacySources(existing["sources"]).filter((source) => source["id"] !== "project-context-bundle");
@@ -8425,9 +8528,9 @@ function writeMetadataSnapshot(plan, now3) {
8425
8528
  const previous = readProjectContextManifest(plan.manifest_path, plan.workspace_root);
8426
8529
  if (!previous || previous.projectContext.revision === plan.bundle.revision && previous.projectContext.hash === plan.bundle.hash)
8427
8530
  return null;
8428
- const snapshotDir = resolve2(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
8531
+ const snapshotDir = resolve4(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
8429
8532
  ensureSafeDirectory(snapshotDir, plan.workspace_root, 448);
8430
- const snapshotPath = resolve2(snapshotDir, `${safeFilename(previous.projectContext.revision)}-${previous.projectContext.hash.slice(-12)}.json`);
8533
+ const snapshotPath = resolve4(snapshotDir, `${safeFilename(previous.projectContext.revision)}-${previous.projectContext.hash.slice(-12)}.json`);
8431
8534
  const snapshot = {
8432
8535
  schema: "hasna.configs.session-render-snapshot/v1",
8433
8536
  kind: "project-context-metadata",
@@ -8443,9 +8546,9 @@ function writeMetadataSnapshot(plan, now3) {
8443
8546
  return snapshotPath;
8444
8547
  }
8445
8548
  function metadataSnapshotMatchesManifest(plan, manifest) {
8446
- const snapshotDir = resolve2(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
8447
- const snapshotPath = resolve2(snapshotDir, `${safeFilename(manifest.projectContext.revision)}-${manifest.projectContext.hash.slice(-12)}.json`);
8448
- if (!existsSync4(snapshotPath))
8549
+ const snapshotDir = resolve4(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
8550
+ const snapshotPath = resolve4(snapshotDir, `${safeFilename(manifest.projectContext.revision)}-${manifest.projectContext.hash.slice(-12)}.json`);
8551
+ if (!existsSync7(snapshotPath))
8449
8552
  return false;
8450
8553
  const record = readJsonRecord(snapshotPath, plan.workspace_root);
8451
8554
  const result = projectContextMetadataSnapshotSchema.safeParse(record);
@@ -8493,10 +8596,10 @@ function writeProjectContextRollbackSnapshot(plan, now3, outputs) {
8493
8596
  sha256: nextHash
8494
8597
  };
8495
8598
  });
8496
- const snapshotDir = resolve2(plan.workspace_root, ...SESSION_RENDER_SNAPSHOT_RELATIVE_DIR.split("/"));
8599
+ const snapshotDir = resolve4(plan.workspace_root, ...SESSION_RENDER_SNAPSHOT_RELATIVE_DIR.split("/"));
8497
8600
  ensureSafeDirectory(snapshotDir, plan.workspace_root, 448);
8498
8601
  const timestamp = now3.toISOString().replace(/[:.]/g, "-");
8499
- const snapshotPath = resolve2(snapshotDir, `${timestamp}-${randomUUID5()}.json`);
8602
+ const snapshotPath = resolve4(snapshotDir, `${timestamp}-${randomUUID5()}.json`);
8500
8603
  const snapshot = {
8501
8604
  schema: "hasna.configs.session-render-snapshot/v2",
8502
8605
  createdAt: now3.toISOString(),
@@ -8514,7 +8617,7 @@ function writeProjectContextRollbackSnapshot(plan, now3, outputs) {
8514
8617
  return snapshotPath;
8515
8618
  }
8516
8619
  function readProjectContextManifest(path, workspaceRoot) {
8517
- if (!existsSync4(path))
8620
+ if (!existsSync7(path))
8518
8621
  return null;
8519
8622
  const record = readJsonRecord(path, workspaceRoot);
8520
8623
  const result = storedManifestObservationSchema.safeParse(record);
@@ -8529,7 +8632,7 @@ function readProjectContextManifest(path, workspaceRoot) {
8529
8632
  };
8530
8633
  }
8531
8634
  function readProjectContextCache(path, workspaceRoot) {
8532
- if (!existsSync4(path))
8635
+ if (!existsSync7(path))
8533
8636
  return null;
8534
8637
  const record = readJsonRecord(path, workspaceRoot);
8535
8638
  const result = projectContextCacheSchema.safeParse(record);
@@ -8561,7 +8664,7 @@ function readSessionManifestRecord(path, workspaceRoot) {
8561
8664
  }
8562
8665
  }
8563
8666
  function atomicWriteFile(path, content, workspaceRoot, defaultMode, expectedHash, afterExchange, atomicExchangeUnavailable = false, beforeInstall, portableCreateOnly = false, maxObservedBytes, allowPortableReplacement = false) {
8564
- const dir = resolve2(path, "..");
8667
+ const dir = resolve4(path, "..");
8565
8668
  ensureSafeDirectory(dir, workspaceRoot, 448);
8566
8669
  assertNoSymlinkSegments(workspaceRoot, path);
8567
8670
  const anchoredOps = portableCreateOnly ? null : resolveAnchoredFsOps();
@@ -8578,7 +8681,7 @@ function atomicWriteFile(path, content, workspaceRoot, defaultMode, expectedHash
8578
8681
  const previous = anchoredFileObservation(directory, targetName);
8579
8682
  const previousMode = previous?.mode ?? defaultMode;
8580
8683
  const tempName = `.project-context-${randomUUID5()}.tmp`;
8581
- const tempPath = join5(dir, tempName);
8684
+ const tempPath = join9(dir, tempName);
8582
8685
  let fd = null;
8583
8686
  let preserveTemp = false;
8584
8687
  let directoryChanged = false;
@@ -8709,7 +8812,7 @@ function atomicWritePortable(path, content, workspaceRoot, defaultMode, expected
8709
8812
  }
8710
8813
  const dir = dirname(path);
8711
8814
  const directoryIdentity = captureManagedDirectoryIdentity(dir, workspaceRoot);
8712
- const tempPath = join5(dir, `.project-context-${randomUUID5()}.tmp`);
8815
+ const tempPath = join9(dir, `.project-context-${randomUUID5()}.tmp`);
8713
8816
  let fd = null;
8714
8817
  let tempIdentity = null;
8715
8818
  try {
@@ -8766,7 +8869,7 @@ function atomicWritePortableReplacement(path, content, workspaceRoot, expectedHa
8766
8869
  }
8767
8870
  const dir = dirname(path);
8768
8871
  const directoryIdentity = captureManagedDirectoryIdentity(dir, workspaceRoot);
8769
- const tempPath = join5(dir, `.project-context-${randomUUID5()}.tmp`);
8872
+ const tempPath = join9(dir, `.project-context-${randomUUID5()}.tmp`);
8770
8873
  const desiredHash = sha2562(content);
8771
8874
  let fd = null;
8772
8875
  let tempIdentity = null;
@@ -8823,7 +8926,7 @@ function portablePreparedHash(tempPath, path, workspaceRoot, maxObservedBytes, s
8823
8926
  function portableFileHash(path, workspaceRoot, maxObservedBytes) {
8824
8927
  if (maxObservedBytes === undefined)
8825
8928
  return currentFileHash(path, workspaceRoot);
8826
- if (!existsSync4(path))
8929
+ if (!existsSync7(path))
8827
8930
  return null;
8828
8931
  assertNoSymlinkSegments(workspaceRoot, path);
8829
8932
  const stat = lstatSync(path);
@@ -8835,11 +8938,11 @@ function portableFileHash(path, workspaceRoot, maxObservedBytes) {
8835
8938
  return createHash2("sha256").update(readFileSync(path)).digest("hex");
8836
8939
  }
8837
8940
  function writeProjectContextCoordinatedFile(input) {
8838
- atomicWriteFile(resolve2(input.path), input.content, assertSafeWorkspaceRoot(input.workspace_root), input.default_mode ?? 420, input.expected_hash, undefined, false, input.test_hooks?.before_install, input.force_portable_file_ops ?? false, input.max_observed_bytes, input.allow_portable_replacement ?? false);
8941
+ atomicWriteFile(resolve4(input.path), input.content, assertSafeWorkspaceRoot(input.workspace_root), input.default_mode ?? 420, input.expected_hash, undefined, false, input.test_hooks?.before_install, input.force_portable_file_ops ?? false, input.max_observed_bytes, input.allow_portable_replacement ?? false);
8839
8942
  }
8840
8943
  function removeProjectContextCoordinatedFile(input) {
8841
8944
  const workspaceRoot = assertSafeWorkspaceRoot(input.workspace_root);
8842
- const path = resolve2(input.path);
8945
+ const path = resolve4(input.path);
8843
8946
  assertNoSymlinkSegments(workspaceRoot, path);
8844
8947
  const dir = dirname(path);
8845
8948
  const anchoredOps = input.force_portable_file_ops ? null : resolveAnchoredFsOps();
@@ -8865,7 +8968,7 @@ function removeProjectContextCoordinatedFile(input) {
8865
8968
  throw new ProjectContextHashRace(`managed path changed during deletion: ${relativePosix(workspaceRoot, path)}`);
8866
8969
  }
8867
8970
  displaced = true;
8868
- input.test_hooks?.after_displace?.(join5(dir, displacedName));
8971
+ input.test_hooks?.after_displace?.(join9(dir, displacedName));
8869
8972
  const moved = anchoredFileObservation(directory, displacedName);
8870
8973
  if (!moved || moved.dev !== observed.dev || moved.ino !== observed.ino || moved.hash !== input.expected_hash || anchoredFileObservation(directory, targetName) !== null) {
8871
8974
  throw new ProjectContextHashRace(`managed path changed during deletion validation: ${relativePosix(workspaceRoot, path)}`);
@@ -8911,7 +9014,7 @@ function removePortableCoordinatedFile(path, workspaceRoot, expectedHash, maxObs
8911
9014
  }
8912
9015
  const dir = dirname(path);
8913
9016
  const directoryIdentity = captureManagedDirectoryIdentity(dir, workspaceRoot);
8914
- const displacedPath = join5(dir, `.project-context-delete-${randomUUID5()}.tmp`);
9017
+ const displacedPath = join9(dir, `.project-context-delete-${randomUUID5()}.tmp`);
8915
9018
  let displaced = false;
8916
9019
  try {
8917
9020
  assertManagedDirectoryStable(dir, workspaceRoot, directoryIdentity);
@@ -8922,7 +9025,7 @@ function removePortableCoordinatedFile(path, workspaceRoot, expectedHash, maxObs
8922
9025
  displaced = true;
8923
9026
  afterDisplace?.(displacedPath);
8924
9027
  const moved = lstatSync(displacedPath);
8925
- if (moved.isSymbolicLink() || !moved.isFile() || moved.dev !== observed.dev || moved.ino !== observed.ino || portableFileHash(displacedPath, workspaceRoot, maxObservedBytes) !== expectedHash || existsSync4(path)) {
9028
+ if (moved.isSymbolicLink() || !moved.isFile() || moved.dev !== observed.dev || moved.ino !== observed.ino || portableFileHash(displacedPath, workspaceRoot, maxObservedBytes) !== expectedHash || existsSync7(path)) {
8926
9029
  throw new ProjectContextHashRace(`managed path changed during portable deletion: ${relativePosix(workspaceRoot, path)}`);
8927
9030
  }
8928
9031
  rmSync2(displacedPath);
@@ -8982,7 +9085,7 @@ function anchoredOpenExclusive(directory, name, mode) {
8982
9085
  const requestedMode = mode & 4095;
8983
9086
  let fd;
8984
9087
  try {
8985
- fd = openSync(join5(directory.path, name), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, requestedMode);
9088
+ fd = openSync(join9(directory.path, name), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, requestedMode);
8986
9089
  } catch {
8987
9090
  throw new ProjectContextHashRace(`could not create prepared managed file in ${relativePosix(directory.workspaceRoot, directory.path)}`);
8988
9091
  }
@@ -9025,7 +9128,7 @@ function anchoredFileObservation(directory, name) {
9025
9128
  const stat = fstatSync(fd);
9026
9129
  if (!stat.isFile())
9027
9130
  throw new ProjectContextHashRace("managed output is not a regular file");
9028
- const relativePath = relativePosix(directory.workspaceRoot, join5(directory.path, name));
9131
+ const relativePath = relativePosix(directory.workspaceRoot, join9(directory.path, name));
9029
9132
  const maxBytes = directory.maxObservedBytes === undefined ? managedObservationMaxBytes(relativePath) : directory.maxObservedBytes;
9030
9133
  if (maxBytes !== null && stat.size > maxBytes) {
9031
9134
  throw new ProjectContextHashRace(`managed output exceeds the safe read limit: ${relativePath}`);
@@ -9051,7 +9154,7 @@ function anchoredPreparedObservation(directory, name, path, stage) {
9051
9154
  return observed;
9052
9155
  }
9053
9156
  function captureManagedDirectoryIdentity(path, workspaceRoot) {
9054
- assertNoSymlinkSegments(workspaceRoot, join5(path, ".project-context-directory-guard"));
9157
+ assertNoSymlinkSegments(workspaceRoot, join9(path, ".project-context-directory-guard"));
9055
9158
  let stat;
9056
9159
  try {
9057
9160
  stat = lstatSync(path);
@@ -9064,7 +9167,7 @@ function captureManagedDirectoryIdentity(path, workspaceRoot) {
9064
9167
  return { dev: stat.dev, ino: stat.ino };
9065
9168
  }
9066
9169
  function assertManagedDirectoryStable(path, workspaceRoot, expected) {
9067
- assertNoSymlinkSegments(workspaceRoot, join5(path, ".project-context-directory-guard"));
9170
+ assertNoSymlinkSegments(workspaceRoot, join9(path, ".project-context-directory-guard"));
9068
9171
  let current;
9069
9172
  try {
9070
9173
  current = lstatSync(path);
@@ -9197,10 +9300,10 @@ function resolveAnchoredFsOps() {
9197
9300
  return null;
9198
9301
  }
9199
9302
  function acquireWorkspaceLock(workspaceRoot, lockPath, afterOpen, beforeStaleRemove, processStartIdentityLookup = processStartIdentity) {
9200
- const lockDirectory = resolve2(lockPath, "..");
9303
+ const lockDirectory = resolve4(lockPath, "..");
9201
9304
  ensureSafeDirectory(lockDirectory, workspaceRoot, 448);
9202
9305
  assertNoSymlinkSegments(workspaceRoot, lockPath);
9203
- const tempPath = join5(lockDirectory, `.project-context-lock-${randomUUID5()}.tmp`);
9306
+ const tempPath = join9(lockDirectory, `.project-context-lock-${randomUUID5()}.tmp`);
9204
9307
  let fd = null;
9205
9308
  let openedIdentity = null;
9206
9309
  let openedContentHash = null;
@@ -9234,7 +9337,7 @@ function acquireWorkspaceLock(workspaceRoot, lockPath, afterOpen, beforeStaleRem
9234
9337
  linked = true;
9235
9338
  }
9236
9339
  fsyncDirectory(lockDirectory);
9237
- if (existsSync4(tempPath)) {
9340
+ if (existsSync7(tempPath)) {
9238
9341
  rmSync2(tempPath);
9239
9342
  fsyncDirectory(lockDirectory);
9240
9343
  }
@@ -9249,7 +9352,7 @@ function acquireWorkspaceLock(workspaceRoot, lockPath, afterOpen, beforeStaleRem
9249
9352
  if (linked && openedIdentity && openedContentHash) {
9250
9353
  removeOwnedLockByInode(lockPath, openedIdentity, openedContentHash);
9251
9354
  }
9252
- if (!preserveTemp && existsSync4(tempPath)) {
9355
+ if (!preserveTemp && existsSync7(tempPath)) {
9253
9356
  try {
9254
9357
  rmSync2(tempPath);
9255
9358
  } catch {}
@@ -9264,7 +9367,7 @@ function acquireWorkspaceLock(workspaceRoot, lockPath, afterOpen, beforeStaleRem
9264
9367
  }
9265
9368
  function removeOwnedLockByInode(lockPath, identity, expectedHash) {
9266
9369
  try {
9267
- if (!existsSync4(lockPath))
9370
+ if (!existsSync7(lockPath))
9268
9371
  return;
9269
9372
  const current = lstatSync(lockPath);
9270
9373
  if (current.isSymbolicLink() || current.dev !== identity.dev || current.ino !== identity.ino)
@@ -9272,7 +9375,7 @@ function removeOwnedLockByInode(lockPath, identity, expectedHash) {
9272
9375
  if (expectedHash !== undefined && sha2562(readFileSync(lockPath, "utf8")) !== expectedHash)
9273
9376
  return;
9274
9377
  rmSync2(lockPath);
9275
- fsyncDirectory(resolve2(lockPath, ".."));
9378
+ fsyncDirectory(resolve4(lockPath, ".."));
9276
9379
  } catch {}
9277
9380
  }
9278
9381
  function observeStaleWorkspaceLock(lockPath, workspaceRoot, processStartIdentityLookup = processStartIdentity) {
@@ -9343,7 +9446,7 @@ function tryTakeoverStaleWorkspaceLock(candidatePath, lockPath, workspaceRoot, c
9343
9446
  const candidateInstalled = !current.isSymbolicLink() && current.dev === candidateIdentity.dev && current.ino === candidateIdentity.ino && currentFileHash(lockPath, workspaceRoot) === candidateHash;
9344
9447
  const staleDisplaced = !displaced.isSymbolicLink() && displaced.dev === stale.identity.dev && displaced.ino === stale.identity.ino && currentFileHash(candidatePath, workspaceRoot) === stale.contentHash;
9345
9448
  if (!candidateInstalled || !staleDisplaced) {
9346
- if (candidateInstalled && existsSync4(candidatePath)) {
9449
+ if (candidateInstalled && existsSync7(candidatePath)) {
9347
9450
  atomicExchangePaths(candidatePath, lockPath);
9348
9451
  exchanged = false;
9349
9452
  return false;
@@ -9351,13 +9454,13 @@ function tryTakeoverStaleWorkspaceLock(candidatePath, lockPath, workspaceRoot, c
9351
9454
  throw new ProjectContextError("PROJECT_CONTEXT_LOCK_LOST", "workspace lock changed during stale-lock takeover and could not be restored safely");
9352
9455
  }
9353
9456
  rmSync2(candidatePath);
9354
- fsyncDirectory(resolve2(lockPath, ".."));
9457
+ fsyncDirectory(resolve4(lockPath, ".."));
9355
9458
  exchanged = false;
9356
9459
  return true;
9357
9460
  } catch (error) {
9358
9461
  if (exchanged) {
9359
9462
  try {
9360
- if (currentFileHash(lockPath, workspaceRoot) === candidateHash && existsSync4(candidatePath)) {
9463
+ if (currentFileHash(lockPath, workspaceRoot) === candidateHash && existsSync7(candidatePath)) {
9361
9464
  atomicExchangePaths(candidatePath, lockPath);
9362
9465
  exchanged = false;
9363
9466
  }
@@ -9370,7 +9473,7 @@ function tryTakeoverStaleWorkspaceLock(candidatePath, lockPath, workspaceRoot, c
9370
9473
  }
9371
9474
  }
9372
9475
  function assertWorkspaceLockHeld(lockPath, lock, workspaceRoot) {
9373
- if (!existsSync4(lockPath)) {
9476
+ if (!existsSync7(lockPath)) {
9374
9477
  throw new ProjectContextError("PROJECT_CONTEXT_LOCK_LOST", "workspace project-context lock changed during render");
9375
9478
  }
9376
9479
  const current = lstatSync(lockPath);
@@ -9430,8 +9533,8 @@ function releaseWorkspaceLock(lockPath, lock, workspaceRoot) {
9430
9533
  }
9431
9534
  return;
9432
9535
  }
9433
- const lockDirectory = resolve2(lockPath, "..");
9434
- const releasePath = join5(lockDirectory, `.project-context-release-${randomUUID5()}.tmp`);
9536
+ const lockDirectory = resolve4(lockPath, "..");
9537
+ const releasePath = join9(lockDirectory, `.project-context-release-${randomUUID5()}.tmp`);
9435
9538
  let releaseFd = null;
9436
9539
  let releaseIdentity = null;
9437
9540
  let releaseHash = null;
@@ -9460,7 +9563,7 @@ function releaseWorkspaceLock(lockPath, lock, workspaceRoot) {
9460
9563
  const releaseInstalled = !installed.isSymbolicLink() && installed.dev === releaseIdentity.dev && installed.ino === releaseIdentity.ino && currentFileHash(lockPath, workspaceRoot) === releaseHash;
9461
9564
  const ownedDisplaced = !displaced.isSymbolicLink() && displaced.dev === lock.identity.dev && displaced.ino === lock.identity.ino && currentFileHash(releasePath, workspaceRoot) === lock.contentHash;
9462
9565
  if (!releaseInstalled || !ownedDisplaced) {
9463
- if (releaseInstalled && existsSync4(releasePath)) {
9566
+ if (releaseInstalled && existsSync7(releasePath)) {
9464
9567
  atomicExchangePaths(releasePath, lockPath);
9465
9568
  exchanged = false;
9466
9569
  }
@@ -9473,7 +9576,7 @@ function releaseWorkspaceLock(lockPath, lock, workspaceRoot) {
9473
9576
  } catch {
9474
9577
  if (exchanged) {
9475
9578
  try {
9476
- if (releaseHash && currentFileHash(lockPath, workspaceRoot) === releaseHash && existsSync4(releasePath)) {
9579
+ if (releaseHash && currentFileHash(lockPath, workspaceRoot) === releaseHash && existsSync7(releasePath)) {
9477
9580
  atomicExchangePaths(releasePath, lockPath);
9478
9581
  exchanged = false;
9479
9582
  }
@@ -9485,7 +9588,7 @@ function releaseWorkspaceLock(lockPath, lock, workspaceRoot) {
9485
9588
  closeSync(releaseFd);
9486
9589
  } catch {}
9487
9590
  }
9488
- if (!exchanged && existsSync4(releasePath)) {
9591
+ if (!exchanged && existsSync7(releasePath)) {
9489
9592
  try {
9490
9593
  rmSync2(releasePath);
9491
9594
  } catch {}
@@ -9511,15 +9614,15 @@ function ensureSafeDirectory(path, workspaceRoot, mode) {
9511
9614
  const segments = rel.split(/[\\/]+/).filter(Boolean);
9512
9615
  let current = workspaceRoot;
9513
9616
  for (const segment of segments) {
9514
- current = join5(current, segment);
9515
- if (existsSync4(current)) {
9617
+ current = join9(current, segment);
9618
+ if (existsSync7(current)) {
9516
9619
  if (lstatSync(current).isSymbolicLink())
9517
9620
  throw new ProjectContextError("PROJECT_CONTEXT_SYMLINK_REJECTED", `managed path uses a symlink: ${current}`);
9518
9621
  if (!statSync(current).isDirectory())
9519
9622
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", `managed path is not a directory: ${current}`);
9520
9623
  } else {
9521
9624
  mkdirSync2(current, { mode });
9522
- fsyncDirectory(resolve2(current, ".."));
9625
+ fsyncDirectory(resolve4(current, ".."));
9523
9626
  }
9524
9627
  }
9525
9628
  }
@@ -9575,11 +9678,11 @@ function scanGeneratedContent(content) {
9575
9678
  function runtimePaths(workspaceRoot, runtime) {
9576
9679
  const relativeTarget = runtime === "claude" ? "CLAUDE.md" : runtime === "codewith" ? ".codewith/CODEWITH.md" : "AGENTS.md";
9577
9680
  return {
9578
- target: resolve2(workspaceRoot, ...relativeTarget.split("/")),
9579
- fragment: resolve2(workspaceRoot, ...PROJECT_CONTEXT_FRAGMENT_PATH.split("/")),
9580
- manifest: resolve2(workspaceRoot, ...PROJECT_CONTEXT_MANIFEST_PATH.split("/")),
9581
- cache: resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/")),
9582
- sessionManifest: runtime === "codewith" ? resolve2(workspaceRoot, ".codewith", ".hasna", "session-render-manifest.json") : resolve2(workspaceRoot, ".hasna", "session-render-manifest.json")
9681
+ target: resolve4(workspaceRoot, ...relativeTarget.split("/")),
9682
+ fragment: resolve4(workspaceRoot, ...PROJECT_CONTEXT_FRAGMENT_PATH.split("/")),
9683
+ manifest: resolve4(workspaceRoot, ...PROJECT_CONTEXT_MANIFEST_PATH.split("/")),
9684
+ cache: resolve4(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/")),
9685
+ sessionManifest: runtime === "codewith" ? resolve4(workspaceRoot, ".codewith", ".hasna", "session-render-manifest.json") : resolve4(workspaceRoot, ".hasna", "session-render-manifest.json")
9583
9686
  };
9584
9687
  }
9585
9688
  function projectContextSessionGuardPaths(paths, runtime) {
@@ -9589,7 +9692,7 @@ function projectContextSessionGuardPaths(paths, runtime) {
9589
9692
  paths.fragment,
9590
9693
  paths.target,
9591
9694
  paths.sessionManifest,
9592
- ...runtime === "codewith" ? [resolve2(paths.target, "..", "CODEWITH.override.md")] : []
9695
+ ...runtime === "codewith" ? [resolve4(paths.target, "..", "CODEWITH.override.md")] : []
9593
9696
  ];
9594
9697
  }
9595
9698
  function sessionTargetRelativePath(runtime) {
@@ -9609,27 +9712,27 @@ function projectContextRuntimeForSessionTool(tool) {
9609
9712
  return null;
9610
9713
  }
9611
9714
  function projectContextWorkspaceForSession(input, runtime) {
9612
- const targetHome = resolve2(input.target_home);
9715
+ const targetHome = resolve4(input.target_home);
9613
9716
  if (runtime === "codewith") {
9614
9717
  const workspaceRoot = basename(targetHome) === ".codewith" ? dirname(targetHome) : null;
9615
9718
  if (!workspaceRoot)
9616
9719
  return null;
9617
- if (input.project_root && resolve2(input.project_root) !== workspaceRoot) {
9720
+ if (input.project_root && resolve4(input.project_root) !== workspaceRoot) {
9618
9721
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", "Codewith project_root must be the parent workspace of target_home");
9619
9722
  }
9620
- if (!existsSync4(workspaceRoot) || !lstatSync(workspaceRoot).isDirectory())
9723
+ if (!existsSync7(workspaceRoot) || !lstatSync(workspaceRoot).isDirectory())
9621
9724
  return null;
9622
9725
  return assertSafeWorkspaceRoot(workspaceRoot);
9623
9726
  }
9624
- if (!existsSync4(targetHome) || !lstatSync(targetHome).isDirectory())
9727
+ if (!existsSync7(targetHome) || !lstatSync(targetHome).isDirectory())
9625
9728
  return null;
9626
9729
  return assertSafeWorkspaceRoot(targetHome);
9627
9730
  }
9628
9731
  function assertCodewithTargetIsConsumed(workspaceRoot, runtime) {
9629
9732
  if (runtime !== "codewith")
9630
9733
  return;
9631
- const override = resolve2(workspaceRoot, ".codewith", "CODEWITH.override.md");
9632
- if (!existsSync4(override))
9734
+ const override = resolve4(workspaceRoot, ".codewith", "CODEWITH.override.md");
9735
+ if (!existsSync7(override))
9633
9736
  return;
9634
9737
  assertNoSymlinkSegments(workspaceRoot, override);
9635
9738
  if (!lstatSync(override).isFile())
@@ -9639,10 +9742,10 @@ function assertCodewithTargetIsConsumed(workspaceRoot, runtime) {
9639
9742
  function assertSafeWorkspaceRoot(path) {
9640
9743
  if (!isAbsolute(path))
9641
9744
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", "workspace root must be absolute");
9642
- const normalized = resolve2(path);
9745
+ const normalized = resolve4(path);
9643
9746
  if (normalized === parse(normalized).root)
9644
9747
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", "workspace root cannot be the filesystem root");
9645
- if (!existsSync4(normalized) || !lstatSync(normalized).isDirectory())
9748
+ if (!existsSync7(normalized) || !lstatSync(normalized).isDirectory())
9646
9749
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", "workspace root must be an existing directory");
9647
9750
  assertNoSymlinkAncestors(normalized);
9648
9751
  if (lstatSync(normalized).isSymbolicLink())
@@ -9656,18 +9759,18 @@ function assertNoSymlinkSegments(root, target) {
9656
9759
  }
9657
9760
  let current = root;
9658
9761
  for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
9659
- current = join5(current, segment);
9660
- if (existsSync4(current) && lstatSync(current).isSymbolicLink()) {
9762
+ current = join9(current, segment);
9763
+ if (existsSync7(current) && lstatSync(current).isSymbolicLink()) {
9661
9764
  throw new ProjectContextError("PROJECT_CONTEXT_SYMLINK_REJECTED", `managed path uses a symlink: ${current}`);
9662
9765
  }
9663
9766
  }
9664
9767
  }
9665
9768
  function assertNoSymlinkAncestors(path) {
9666
- const normalized = resolve2(path);
9769
+ const normalized = resolve4(path);
9667
9770
  let current = parse(normalized).root;
9668
9771
  for (const segment of relative(current, normalized).split(/[\\/]+/).filter(Boolean)) {
9669
- current = join5(current, segment);
9670
- if (!existsSync4(current))
9772
+ current = join9(current, segment);
9773
+ if (!existsSync7(current))
9671
9774
  return;
9672
9775
  if (lstatSync(current).isSymbolicLink())
9673
9776
  throw new ProjectContextError("PROJECT_CONTEXT_SYMLINK_REJECTED", `workspace ancestor is a symlink: ${current}`);
@@ -9683,7 +9786,7 @@ function readUtf8RegularFile(path, workspaceRoot, maxBytes = FOREIGN_INPUT_MAX_B
9683
9786
  return readFileSync(path, "utf8");
9684
9787
  }
9685
9788
  function currentFileHash(path, workspaceRoot) {
9686
- if (!existsSync4(path))
9789
+ if (!existsSync7(path))
9687
9790
  return null;
9688
9791
  const relativePath = relativePosix(workspaceRoot, path);
9689
9792
  return sha2562(readUtf8RegularFile(path, workspaceRoot, managedObservationMaxBytes(relativePath)));
@@ -9702,10 +9805,10 @@ function fragmentMatchesBundle(path, bundle, workspaceRoot) {
9702
9805
  }
9703
9806
  function durableSourcePath(path, workspaceRoot) {
9704
9807
  if (!path || path.startsWith("/dev/fd/"))
9705
- return resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
9706
- const normalized = isAbsolute(path) ? resolve2(path) : resolve2(workspaceRoot, path);
9808
+ return resolve4(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
9809
+ const normalized = isAbsolute(path) ? resolve4(path) : resolve4(workspaceRoot, path);
9707
9810
  if (normalized.startsWith("/dev/fd/"))
9708
- return resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
9811
+ return resolve4(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
9709
9812
  return normalized;
9710
9813
  }
9711
9814
  function compareRevisions(incoming, previous) {
@@ -10265,7 +10368,7 @@ function compareProviderVersions(left, right) {
10265
10368
 
10266
10369
  // src/lib/asset-plan.ts
10267
10370
  import { createHash as createHash3 } from "crypto";
10268
- import { isAbsolute as isAbsolute2, posix, resolve as resolve3 } from "path";
10371
+ import { isAbsolute as isAbsolute2, posix, resolve as resolve5 } from "path";
10269
10372
  function assetCapability(provider, surface, kind, support, strategies, note, providerVersionRange = "*") {
10270
10373
  return Object.freeze({
10271
10374
  schema: ASSET_CAPABILITY_SCHEMA,
@@ -10472,8 +10575,8 @@ function resolveAssetDestination(item, roots) {
10472
10575
  if (!isAbsolute2(root))
10473
10576
  throw new Error(`Asset ${item.assetKey} destination root must be absolute.`);
10474
10577
  const relativePath = safeRelativePath(item.destination.relativePath);
10475
- const target = resolve3(root, ...relativePath.split("/"));
10476
- const normalizedRoot = resolve3(root);
10578
+ const target = resolve5(root, ...relativePath.split("/"));
10579
+ const normalizedRoot = resolve5(root);
10477
10580
  if (target === normalizedRoot)
10478
10581
  throw new Error(`Asset ${item.assetKey} destination cannot replace its root.`);
10479
10582
  if (!target.startsWith(`${normalizedRoot}/`))
@@ -10653,13 +10756,13 @@ var init_asset_plan = __esm(() => {
10653
10756
  // src/lib/cursor-authority.ts
10654
10757
  import { createHash as createHash4 } from "crypto";
10655
10758
  import { lstatSync as lstatSync2, readFileSync as readFileSync2 } from "fs";
10656
- import { homedir as homedir4 } from "os";
10657
- import { join as join6, resolve as resolve4 } from "path";
10759
+ import { homedir as homedir7 } from "os";
10760
+ import { join as join10, resolve as resolve6 } from "path";
10658
10761
  function sha2564(content) {
10659
10762
  return createHash4("sha256").update(content).digest("hex");
10660
10763
  }
10661
- function homeDir() {
10662
- return process.env["HOME"] || homedir4();
10764
+ function homeDir2() {
10765
+ return process.env["HOME"] || homedir7();
10663
10766
  }
10664
10767
  function markerPayload(content, markerLine, markerIndex) {
10665
10768
  const index = markerIndex ?? content.indexOf(markerLine);
@@ -10675,12 +10778,12 @@ function baseObservation(path) {
10675
10778
  };
10676
10779
  }
10677
10780
  function observeCursorGlobalAuthority(options = {}) {
10678
- const authorityPath = resolve4(join6(options.home ?? homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
10781
+ const authorityPath = resolve6(join10(options.home ?? homeDir2(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
10679
10782
  const readFile2 = options.readFile ?? ((path) => readFileSync2(path, "utf8"));
10680
10783
  return observeCursorGlobalAuthorityPath(authorityPath, readFile2);
10681
10784
  }
10682
10785
  function observeCursorGlobalAuthorityAtPath(authorityPath) {
10683
- return observeCursorGlobalAuthorityPath(resolve4(authorityPath), (path) => readFileSync2(path, "utf8"));
10786
+ return observeCursorGlobalAuthorityPath(resolve6(authorityPath), (path) => readFileSync2(path, "utf8"));
10684
10787
  }
10685
10788
  function observeCursorGlobalAuthorityPath(authorityPath, readFile2) {
10686
10789
  const base = baseObservation(authorityPath);
@@ -10825,7 +10928,7 @@ function observeCursorGlobalAuthorityPath(authorityPath, readFile2) {
10825
10928
  };
10826
10929
  }
10827
10930
  function isCursorGlobalAuthorityPath(path) {
10828
- return resolve4(path) === resolve4(join6(homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
10931
+ return resolve6(path) === resolve6(join10(homeDir2(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
10829
10932
  }
10830
10933
  function stampCursorGlobalAuthorityMarker(content) {
10831
10934
  const existing = content.match(CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN);
@@ -10881,16 +10984,16 @@ var init_cursor_authority = __esm(() => {
10881
10984
  // src/lib/session-authority.ts
10882
10985
  import { createHash as createHash5 } from "crypto";
10883
10986
  import { lstatSync as lstatSync3, readFileSync as readFileSync3, realpathSync, statSync as statSync2 } from "fs";
10884
- import { homedir as homedir5 } from "os";
10885
- import { join as join7, resolve as resolve5 } from "path";
10987
+ import { homedir as homedir8 } from "os";
10988
+ import { join as join11, resolve as resolve7 } from "path";
10886
10989
  function sha2565(content) {
10887
10990
  return createHash5("sha256").update(content).digest("hex");
10888
10991
  }
10889
10992
  function configHomeDir() {
10890
- return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir5();
10993
+ return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir8();
10891
10994
  }
10892
10995
  function normalizeOwnedTargetPath(p) {
10893
- const expanded = p.startsWith("~/") ? resolve5(configHomeDir(), p.slice(2)) : resolve5(p);
10996
+ const expanded = p.startsWith("~/") ? resolve7(configHomeDir(), p.slice(2)) : resolve7(p);
10894
10997
  try {
10895
10998
  return realpathSync(expanded);
10896
10999
  } catch {
@@ -10898,7 +11001,7 @@ function normalizeOwnedTargetPath(p) {
10898
11001
  }
10899
11002
  }
10900
11003
  function detectClaudeAuthorityConflicts(targetHome, ownedAuthorities = []) {
10901
- const authorityPath = resolve5(join7(targetHome, CLAUDE_LEGACY_AUTHORITY_RELATIVE_PATH));
11004
+ const authorityPath = resolve7(join11(targetHome, CLAUDE_LEGACY_AUTHORITY_RELATIVE_PATH));
10902
11005
  let stat;
10903
11006
  try {
10904
11007
  stat = lstatSync3(authorityPath);
@@ -10987,9 +11090,9 @@ var init_session_authority = __esm(() => {
10987
11090
 
10988
11091
  // src/lib/session-render.ts
10989
11092
  import { createHash as createHash6 } from "crypto";
10990
- import { existsSync as existsSync6, readFileSync as readFileSync4, realpathSync as realpathSync2, statSync as statSync3 } from "fs";
10991
- import { homedir as homedir6 } from "os";
10992
- import { basename as basename4, dirname as dirname3, extname as extname2, isAbsolute as isAbsolute3, join as join8, parse as parse2, posix as posix2, relative as relative2, resolve as resolve6 } from "path";
11093
+ import { existsSync as existsSync9, readFileSync as readFileSync4, realpathSync as realpathSync2, statSync as statSync3 } from "fs";
11094
+ import { homedir as homedir9 } from "os";
11095
+ import { basename as basename4, dirname as dirname3, extname as extname2, isAbsolute as isAbsolute3, join as join12, parse as parse2, posix as posix2, relative as relative2, resolve as resolve8 } from "path";
10993
11096
  function normalizeSessionInstructionLayer(value) {
10994
11097
  if (value === "provider")
10995
11098
  return "tool";
@@ -11075,13 +11178,13 @@ function yamlQuote2(value) {
11075
11178
  return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
11076
11179
  }
11077
11180
  function defaultTargetHome(tool, profile, sessionId) {
11078
- const home = process.env["HOME"] || homedir6();
11079
- return join8(home, ".hasna", "accounts", "profiles", tool, slug(profile));
11181
+ const home = process.env["HOME"] || homedir9();
11182
+ return join12(home, ".hasna", "accounts", "profiles", tool, slug(profile));
11080
11183
  }
11081
11184
  function joinTarget(targetHome, relativePath) {
11082
11185
  const safeTargetHome = assertSafeTargetRoot(targetHome);
11083
11186
  const safeRelativePath2 = assertSafeRelativePath(relativePath);
11084
- return join8(safeTargetHome, ...safeRelativePath2.split("/"));
11187
+ return join12(safeTargetHome, ...safeRelativePath2.split("/"));
11085
11188
  }
11086
11189
  function makeFile(targetHome, relativePath, role, content, sourceIds) {
11087
11190
  const safeTargetHome = assertSafeTargetRoot(targetHome);
@@ -11650,7 +11753,7 @@ function buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfi
11650
11753
  ...sources.flatMap((source) => source.resolvedRules.map((rule) => rule.id))
11651
11754
  ]);
11652
11755
  const existingConfigPath = joinTarget(targetHome, adapter.configFile);
11653
- const selectedConfig = existsSync6(existingConfigPath) ? readOpenCodeConfig(readFileSync4(existingConfigPath, "utf8"), existingConfigPath) : providerConfig ? readOpenCodeConfig(providerConfig.content, providerConfig.sourceId) : {};
11756
+ const selectedConfig = existsSync9(existingConfigPath) ? readOpenCodeConfig(readFileSync4(existingConfigPath, "utf8"), existingConfigPath) : providerConfig ? readOpenCodeConfig(providerConfig.content, providerConfig.sourceId) : {};
11654
11757
  const preservedInstructions = normalizeOpenCodeInstructions(selectedConfig["instructions"]).filter((path) => !pathIsManagedOpenCodeInstruction(path, adapter.managedDir));
11655
11758
  const config = {
11656
11759
  ...selectedConfig,
@@ -11839,7 +11942,7 @@ function adapterFor(input) {
11839
11942
  return gatedNativeImports ? CODEWITH_NATIVE_ADAPTER : CODEWITH_FLATTENED_ADAPTER;
11840
11943
  }
11841
11944
  function getHomeDir() {
11842
- return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir6();
11945
+ return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir9();
11843
11946
  }
11844
11947
  function cleanSessionPathInput(path) {
11845
11948
  const trimmed = path.trim();
@@ -11854,16 +11957,16 @@ function resolveSessionPath(path) {
11854
11957
  throw new Error("Session render path cannot be empty.");
11855
11958
  const home = getHomeDir();
11856
11959
  if (cleaned === "~")
11857
- return resolve6(home);
11960
+ return resolve8(home);
11858
11961
  if (cleaned.startsWith("~/"))
11859
- return resolve6(home, cleaned.slice(2));
11962
+ return resolve8(home, cleaned.slice(2));
11860
11963
  if (cleaned === "{{HOME}}" || cleaned === "${HOME}")
11861
- return resolve6(home);
11964
+ return resolve8(home);
11862
11965
  if (cleaned.startsWith("{{HOME}}/"))
11863
- return resolve6(home, cleaned.slice("{{HOME}}/".length));
11966
+ return resolve8(home, cleaned.slice("{{HOME}}/".length));
11864
11967
  if (cleaned.startsWith("${HOME}/"))
11865
- return resolve6(home, cleaned.slice("${HOME}/".length));
11866
- return resolve6(cleaned);
11968
+ return resolve8(home, cleaned.slice("${HOME}/".length));
11969
+ return resolve8(cleaned);
11867
11970
  }
11868
11971
  function assertSafeRelativePath(relativePath) {
11869
11972
  if (!relativePath.trim())
@@ -11879,7 +11982,7 @@ function assertSafeRelativePath(relativePath) {
11879
11982
  function assertSafeTargetRoot(targetHome) {
11880
11983
  if (!isAbsolute3(targetHome))
11881
11984
  throw new Error(`Session render target must be an absolute path: ${targetHome}`);
11882
- const normalized = resolve6(targetHome);
11985
+ const normalized = resolve8(targetHome);
11883
11986
  if (normalized === parse2(normalized).root) {
11884
11987
  throw new Error(`Session render target cannot be the filesystem root: ${targetHome}`);
11885
11988
  }
@@ -12115,7 +12218,7 @@ function planSessionRender(input) {
12115
12218
  sourceId: input.providerConfig.sourceId,
12116
12219
  selectedPayloadSha256: sha2566(input.providerConfig.content),
12117
12220
  renderedPayloadSha256: files.find((file) => file.relativePath === adapter.configFile)?.sha256 ?? sha2566(input.providerConfig.content),
12118
- selected: !existsSync6(joinTarget(targetHome, adapter.configFile))
12221
+ selected: !existsSync9(joinTarget(targetHome, adapter.configFile))
12119
12222
  }
12120
12223
  } : {},
12121
12224
  ...projectContext ? {
@@ -12376,10 +12479,10 @@ function layerFromIdentityKind(kind, exportShape) {
12376
12479
  function contentFromIdentitySourcePaths(sourcePaths, exportPath, sourceId) {
12377
12480
  if (sourcePaths.length === 0 || !exportPath)
12378
12481
  return;
12379
- const baseDir = dirname3(resolveSessionPath(exportPath));
12482
+ const baseDir3 = dirname3(resolveSessionPath(exportPath));
12380
12483
  const contents = [];
12381
12484
  for (const sourcePath of sourcePaths) {
12382
- const content = readIdentitySourcePath(sourcePath, baseDir, sourceId);
12485
+ const content = readIdentitySourcePath(sourcePath, baseDir3, sourceId);
12383
12486
  if (content !== undefined)
12384
12487
  contents.push({ path: sourcePath.path, content });
12385
12488
  }
@@ -12392,9 +12495,9 @@ ${item.content.trimEnd()}`).join(`
12392
12495
 
12393
12496
  `));
12394
12497
  }
12395
- function readIdentitySourcePath(sourcePath, baseDir, sourceId) {
12396
- const resolvedPath = resolveIdentitySourcePath(sourcePath.path, baseDir, sourceId);
12397
- if (!existsSync6(resolvedPath)) {
12498
+ function readIdentitySourcePath(sourcePath, baseDir3, sourceId) {
12499
+ const resolvedPath = resolveIdentitySourcePath(sourcePath.path, baseDir3, sourceId);
12500
+ if (!existsSync9(resolvedPath)) {
12398
12501
  if (sourcePath.required) {
12399
12502
  throw new Error(`Required identity instruction source path not found for ${sourceId}: ${sourcePath.path}`);
12400
12503
  }
@@ -12404,27 +12507,27 @@ function readIdentitySourcePath(sourcePath, baseDir, sourceId) {
12404
12507
  if (!stat.isFile()) {
12405
12508
  throw new Error(`Identity instruction source path is not a file for ${sourceId}: ${sourcePath.path}`);
12406
12509
  }
12407
- const realBase = realpathSync2(baseDir);
12510
+ const realBase = realpathSync2(baseDir3);
12408
12511
  const realPath = realpathSync2(resolvedPath);
12409
12512
  if (!pathIsInside(realPath, realBase)) {
12410
12513
  throw new Error(`Identity instruction source path escapes export directory for ${sourceId}: ${sourcePath.path}`);
12411
12514
  }
12412
12515
  return readFileSync4(realPath, "utf-8");
12413
12516
  }
12414
- function resolveIdentitySourcePath(path, baseDir, sourceId) {
12517
+ function resolveIdentitySourcePath(path, baseDir3, sourceId) {
12415
12518
  const cleaned = cleanSessionPathInput(path);
12416
12519
  if (!cleaned)
12417
12520
  throw new Error(`Identity instruction source path cannot be empty for ${sourceId}.`);
12418
12521
  if (cleaned.includes("\\"))
12419
12522
  throw new Error(`Identity instruction source path must use POSIX separators for ${sourceId}: ${path}`);
12420
- const resolvedPath = isAbsolute3(cleaned) ? resolve6(cleaned) : resolve6(baseDir, cleaned);
12421
- if (!pathIsInside(resolvedPath, resolve6(baseDir))) {
12523
+ const resolvedPath = isAbsolute3(cleaned) ? resolve8(cleaned) : resolve8(baseDir3, cleaned);
12524
+ if (!pathIsInside(resolvedPath, resolve8(baseDir3))) {
12422
12525
  throw new Error(`Identity instruction source path escapes export directory for ${sourceId}: ${path}`);
12423
12526
  }
12424
12527
  return resolvedPath;
12425
12528
  }
12426
- function pathIsInside(path, baseDir) {
12427
- const rel = relative2(baseDir, path);
12529
+ function pathIsInside(path, baseDir3) {
12530
+ const rel = relative2(baseDir3, path);
12428
12531
  return rel === "" || !rel.startsWith("..") && !isAbsolute3(rel);
12429
12532
  }
12430
12533
  function providerTargetsTool(targets, tool) {
@@ -14084,8 +14187,8 @@ var init_config_store = __esm(() => {
14084
14187
  });
14085
14188
 
14086
14189
  // src/lib/session-render-ownership.ts
14087
- import { existsSync as existsSync7, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
14088
- import { dirname as dirname4, join as join9, parse as parse3, relative as relative3, sep } from "path";
14190
+ import { existsSync as existsSync10, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
14191
+ import { dirname as dirname4, join as join13, parse as parse3, relative as relative3, sep } from "path";
14089
14192
  function toSegments(absolutePath2) {
14090
14193
  return absolutePath2.replaceAll("\\", "/").split("/").filter(Boolean);
14091
14194
  }
@@ -14104,7 +14207,7 @@ function pathIsSessionRenderManagedDir(absolutePath2) {
14104
14207
  function readManifestRelativePaths(manifestPath) {
14105
14208
  let stats;
14106
14209
  try {
14107
- if (!existsSync7(manifestPath))
14210
+ if (!existsSync10(manifestPath))
14108
14211
  return null;
14109
14212
  stats = statSync4(manifestPath);
14110
14213
  } catch {
@@ -14133,7 +14236,7 @@ function sessionRenderManifestClaimsPath(absolutePath2) {
14133
14236
  const root = parse3(absolutePath2).root;
14134
14237
  let home = dirname4(absolutePath2);
14135
14238
  for (let depth = 0;depth < MANIFEST_ANCESTOR_LIMIT; depth += 1) {
14136
- const manifestPath = join9(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
14239
+ const manifestPath = join13(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
14137
14240
  const relativePaths = readManifestRelativePaths(manifestPath);
14138
14241
  if (relativePaths) {
14139
14242
  const claimed = relative3(home, absolutePath2).split(sep).join("/");
@@ -14168,17 +14271,17 @@ __export(exports_apply, {
14168
14271
  applyConfigs: () => applyConfigs,
14169
14272
  applyConfig: () => applyConfig
14170
14273
  });
14171
- import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync6, realpathSync as realpathSync3, writeFileSync as writeFileSync2 } from "fs";
14172
- import { basename as basename5, dirname as dirname5, join as join10, resolve as resolve7 } from "path";
14173
- import { homedir as homedir7 } from "os";
14274
+ import { existsSync as existsSync11, mkdirSync as mkdirSync3, readFileSync as readFileSync6, realpathSync as realpathSync3, writeFileSync as writeFileSync2 } from "fs";
14275
+ import { basename as basename5, dirname as dirname5, join as join14, resolve as resolve9 } from "path";
14276
+ import { homedir as homedir10 } from "os";
14174
14277
  function getConfigHome() {
14175
- return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir7();
14278
+ return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir10();
14176
14279
  }
14177
14280
  function expandPath(p) {
14178
14281
  if (p.startsWith("~/")) {
14179
- return resolve7(getConfigHome(), p.slice(2));
14282
+ return resolve9(getConfigHome(), p.slice(2));
14180
14283
  }
14181
- return resolve7(p);
14284
+ return resolve9(p);
14182
14285
  }
14183
14286
  function normalizeTargetPath(p) {
14184
14287
  const expanded = expandPath(p);
@@ -14188,9 +14291,9 @@ function normalizeTargetPath(p) {
14188
14291
  let current = expanded;
14189
14292
  const missingSegments = [];
14190
14293
  while (true) {
14191
- if (existsSync8(current)) {
14294
+ if (existsSync11(current)) {
14192
14295
  try {
14193
- return resolve7(realpathSync3(current), ...missingSegments);
14296
+ return resolve9(realpathSync3(current), ...missingSegments);
14194
14297
  } catch {
14195
14298
  return expanded;
14196
14299
  }
@@ -14219,11 +14322,11 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
14219
14322
  }
14220
14323
  const path = expandPath(renderedTargetPath);
14221
14324
  const renderedForTarget = isCursorGlobalAuthorityPath(path) ? stampCursorGlobalAuthorityMarker(renderedContent) : renderedContent;
14222
- const previousContent = existsSync8(path) ? readFileSync6(path, "utf-8") : null;
14325
+ const previousContent = existsSync11(path) ? readFileSync6(path, "utf-8") : null;
14223
14326
  const changed = previousContent !== renderedForTarget;
14224
14327
  if (!opts.dryRun) {
14225
14328
  const dir = dirname5(path);
14226
- if (!existsSync8(dir)) {
14329
+ if (!existsSync11(dir)) {
14227
14330
  mkdirSync3(dir, { recursive: true });
14228
14331
  }
14229
14332
  if (previousContent !== null && changed) {
@@ -14257,7 +14360,7 @@ function wouldDestroyACredential(targetPath, renderedContent, format) {
14257
14360
  let current;
14258
14361
  try {
14259
14362
  const path = expandPath(targetPath);
14260
- if (!existsSync8(path))
14363
+ if (!existsSync11(path))
14261
14364
  return [];
14262
14365
  current = readFileSync6(path, "utf-8");
14263
14366
  } catch {
@@ -14583,7 +14686,7 @@ function sessionRendererOwnsCanonicalTarget(normalized, opts) {
14583
14686
  getConfigHome(),
14584
14687
  opts.vars?.["HOME_DIR"]
14585
14688
  ].filter((home) => typeof home === "string" && home.length > 0));
14586
- if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join10(home, ...relativePath.split("/"))))))
14689
+ if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join14(home, ...relativePath.split("/"))))))
14587
14690
  return true;
14588
14691
  return sessionRenderOwnsPath(normalized);
14589
14692
  }
@@ -14601,20 +14704,20 @@ var init_apply = __esm(() => {
14601
14704
  });
14602
14705
 
14603
14706
  // src/lib/sync-dir.ts
14604
- import { existsSync as existsSync9, readdirSync, readFileSync as readFileSync7, statSync as statSync5 } from "fs";
14605
- import { join as join11, relative as relative4 } from "path";
14606
- import { homedir as homedir8 } from "os";
14707
+ import { existsSync as existsSync12, readdirSync, readFileSync as readFileSync7, statSync as statSync5 } from "fs";
14708
+ import { join as join15, relative as relative4 } from "path";
14709
+ import { homedir as homedir11 } from "os";
14607
14710
  function shouldSkip(p) {
14608
14711
  return SKIP.some((s) => p.includes(s));
14609
14712
  }
14610
14713
  async function syncFromDir(dir, opts = {}) {
14611
14714
  const store = opts.store ?? resolveConfigStore();
14612
14715
  const absDir = expandPath(dir);
14613
- if (!existsSync9(absDir))
14716
+ if (!existsSync12(absDir))
14614
14717
  return { added: 0, updated: 0, unchanged: 0, skipped: [`Not found: ${absDir}`] };
14615
- const files = opts.recursive !== false ? walkDir(absDir) : readdirSync(absDir).map((f) => join11(absDir, f)).filter((f) => statSync5(f).isFile());
14718
+ const files = opts.recursive !== false ? walkDir(absDir) : readdirSync(absDir).map((f) => join15(absDir, f)).filter((f) => statSync5(f).isFile());
14616
14719
  const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
14617
- const home = homedir8();
14720
+ const home = homedir11();
14618
14721
  const allConfigs = await store.listConfigs();
14619
14722
  for (const file of files) {
14620
14723
  if (shouldSkip(file)) {
@@ -14649,7 +14752,7 @@ async function syncFromDir(dir, opts = {}) {
14649
14752
  }
14650
14753
  async function syncToDir(dir, opts = {}) {
14651
14754
  const store = opts.store ?? resolveConfigStore();
14652
- const home = homedir8();
14755
+ const home = homedir11();
14653
14756
  const absDir = expandPath(dir);
14654
14757
  const normalized = dir.startsWith("~/") ? dir : absDir.replace(home, "~");
14655
14758
  const configs = (await store.listConfigs()).filter((c) => c.target_path && (c.target_path.startsWith(normalized) || c.target_path.startsWith(absDir)));
@@ -14673,7 +14776,7 @@ async function syncToDir(dir, opts = {}) {
14673
14776
  }
14674
14777
  function walkDir(dir, files = []) {
14675
14778
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
14676
- const full = join11(dir, entry.name);
14779
+ const full = join15(dir, entry.name);
14677
14780
  if (shouldSkip(full))
14678
14781
  continue;
14679
14782
  if (entry.isDirectory())
@@ -14708,8 +14811,8 @@ __export(exports_sync, {
14708
14811
  KNOWN_CONFIGS: () => KNOWN_CONFIGS,
14709
14812
  CLAUDE_PROMPT_OUTPUTS: () => CLAUDE_PROMPT_OUTPUTS
14710
14813
  });
14711
- import { existsSync as existsSync10, readdirSync as readdirSync2, readFileSync as readFileSync8 } from "fs";
14712
- import { basename as basename6, extname as extname3, join as join12 } from "path";
14814
+ import { existsSync as existsSync13, readdirSync as readdirSync2, readFileSync as readFileSync8 } from "fs";
14815
+ import { basename as basename6, extname as extname3, join as join16 } from "path";
14713
14816
  function claudeRuleOutputs(fileName) {
14714
14817
  const stem = basename6(fileName, extname3(fileName));
14715
14818
  return [
@@ -14748,7 +14851,7 @@ function isGeneratedOutputTarget2(config, owners) {
14748
14851
  return !!ownerIds && !ownerIds.has(config.id);
14749
14852
  }
14750
14853
  function hasClaudePromptSource() {
14751
- return existsSync10(expandPath("~/.claude/CLAUDE.md"));
14854
+ return existsSync13(expandPath("~/.claude/CLAUDE.md"));
14752
14855
  }
14753
14856
  function hasClaudeRuleSourceForCursorTarget(targetPath) {
14754
14857
  const absoluteTargetPath = expandPath(targetPath);
@@ -14756,7 +14859,7 @@ function hasClaudeRuleSourceForCursorTarget(targetPath) {
14756
14859
  if (!absoluteTargetPath.startsWith(`${absolutePrefix}/`) || !absoluteTargetPath.endsWith(".mdc"))
14757
14860
  return false;
14758
14861
  const stem = basename6(absoluteTargetPath, ".mdc");
14759
- return existsSync10(expandPath(`~/.claude/rules/${stem}.md`)) || existsSync10(expandPath(`~/.claude/rules/${stem}.mdc`));
14862
+ return existsSync13(expandPath(`~/.claude/rules/${stem}.md`)) || existsSync13(expandPath(`~/.claude/rules/${stem}.mdc`));
14760
14863
  }
14761
14864
  function isKnownGeneratedTargetPath(targetPath) {
14762
14865
  const normalizedTargetPath = normalizeTargetPath(targetPath);
@@ -14773,8 +14876,8 @@ async function syncProject(opts) {
14773
14876
  const allConfigs = await store.listConfigs();
14774
14877
  const machine = detectMachineContext();
14775
14878
  for (const pf of PROJECT_CONFIG_FILES) {
14776
- const abs = join12(absDir, pf.file);
14777
- if (!existsSync10(abs))
14879
+ const abs = join16(absDir, pf.file);
14880
+ if (!existsSync13(abs))
14778
14881
  continue;
14779
14882
  try {
14780
14883
  const rawContent = readFileSync8(abs, "utf-8");
@@ -14806,19 +14909,19 @@ async function syncProject(opts) {
14806
14909
  }
14807
14910
  }
14808
14911
  for (const ruleDir of [
14809
- { dir: join12(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
14810
- { dir: join12(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
14811
- { dir: join12(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
14812
- { dir: join12(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
14813
- { dir: join12(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
14814
- { dir: join12(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
14815
- { dir: join12(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
14912
+ { dir: join16(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
14913
+ { dir: join16(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
14914
+ { dir: join16(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
14915
+ { dir: join16(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
14916
+ { dir: join16(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
14917
+ { dir: join16(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
14918
+ { dir: join16(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
14816
14919
  ]) {
14817
- if (!existsSync10(ruleDir.dir))
14920
+ if (!existsSync13(ruleDir.dir))
14818
14921
  continue;
14819
14922
  const mdFiles = readdirSync2(ruleDir.dir).filter((f) => f.endsWith(".md") || f.endsWith(".mdc"));
14820
14923
  for (const f of mdFiles) {
14821
- const abs = join12(ruleDir.dir, f);
14924
+ const abs = join16(ruleDir.dir, f);
14822
14925
  const raw = readFileSync8(abs, "utf-8");
14823
14926
  const redacted = redactContent(raw, "markdown");
14824
14927
  const machineAware = templateizeMachineContent(redacted.content, machine);
@@ -14858,14 +14961,14 @@ async function syncKnown(opts = {}) {
14858
14961
  for (const known of targets) {
14859
14962
  if (known.rulesDir) {
14860
14963
  const absDir = expandPath(known.rulesDir);
14861
- if (!existsSync10(absDir)) {
14964
+ if (!existsSync13(absDir)) {
14862
14965
  result.skipped.push(known.rulesDir);
14863
14966
  continue;
14864
14967
  }
14865
14968
  const extensions = known.rulesExtensions ?? [".md", ".mdc"];
14866
14969
  const ruleFiles = readdirSync2(absDir).filter((f) => extensions.some((ext) => f.endsWith(ext)));
14867
14970
  for (const f of ruleFiles) {
14868
- const abs2 = join12(absDir, f);
14971
+ const abs2 = join16(absDir, f);
14869
14972
  const targetPath = abs2.replace(home, "~");
14870
14973
  if (existingOutputOwners.has(normalizeTargetPath(targetPath)) || isKnownGeneratedTargetPath(targetPath)) {
14871
14974
  result.skipped.push(`${targetPath} (generated output)`);
@@ -14899,7 +15002,7 @@ async function syncKnown(opts = {}) {
14899
15002
  continue;
14900
15003
  }
14901
15004
  const abs = expandPath(known.path);
14902
- if (!existsSync10(abs)) {
15005
+ if (!existsSync13(abs)) {
14903
15006
  result.skipped.push(known.path);
14904
15007
  continue;
14905
15008
  }
@@ -15005,7 +15108,7 @@ function storedPlaceholderIsLiteralOnDisk(storedLine, diskLine) {
15005
15108
  }
15006
15109
  function buildDiff(expectedContent, targetPath, storedFormat, showSecrets) {
15007
15110
  const path = expandPath(targetPath);
15008
- if (!existsSync10(path))
15111
+ if (!existsSync13(path))
15009
15112
  return `(file not found on disk: ${path})`;
15010
15113
  const diskContent = readFileSync8(path, "utf-8");
15011
15114
  if (diskContent === expectedContent)
@@ -15240,16 +15343,16 @@ __export(exports_package_manager_guard, {
15240
15343
  scanPackageManagerSecrets: () => scanPackageManagerSecrets
15241
15344
  });
15242
15345
  import { execFileSync as execFileSync2 } from "child_process";
15243
- import { existsSync as existsSync19, lstatSync as lstatSync7, readdirSync as readdirSync5, readFileSync as readFileSync16 } from "fs";
15244
- import { homedir as homedir11 } from "os";
15245
- import { basename as basename7, dirname as dirname10, isAbsolute as isAbsolute5, join as join20, relative as relative7, resolve as resolve13 } from "path";
15346
+ import { existsSync as existsSync22, lstatSync as lstatSync7, readdirSync as readdirSync5, readFileSync as readFileSync16 } from "fs";
15347
+ import { homedir as homedir14 } from "os";
15348
+ import { basename as basename7, dirname as dirname10, isAbsolute as isAbsolute5, join as join24, relative as relative7, resolve as resolve14 } from "path";
15246
15349
  function scanPackageManagerSecrets(options = {}) {
15247
- const cwd = options.cwd ? resolve13(options.cwd) : process.cwd();
15248
- const roots = (options.roots && options.roots.length > 0 ? options.roots : [cwd]).map((root) => resolve13(cwd, root));
15350
+ const cwd = options.cwd ? resolve14(options.cwd) : process.cwd();
15351
+ const roots = (options.roots && options.roots.length > 0 ? options.roots : [cwd]).map((root) => resolve14(cwd, root));
15249
15352
  const findings = [];
15250
15353
  let scannedFiles = 0;
15251
15354
  for (const root of roots) {
15252
- if (!existsSync19(root))
15355
+ if (!existsSync22(root))
15253
15356
  continue;
15254
15357
  const stat = lstatSync7(root);
15255
15358
  if (stat.isFile()) {
@@ -15276,10 +15379,10 @@ function scanPackageManagerSecrets(options = {}) {
15276
15379
  }
15277
15380
  }
15278
15381
  if (options.includeHome) {
15279
- const home = homedir11();
15382
+ const home = homedir14();
15280
15383
  for (const name of HOME_FILES) {
15281
- const file = join20(home, name);
15282
- if (!existsSync19(file))
15384
+ const file = join24(home, name);
15385
+ if (!existsSync22(file))
15283
15386
  continue;
15284
15387
  const text = readTextFile(file);
15285
15388
  if (text === null)
@@ -15303,12 +15406,12 @@ function collectRepoFiles(root) {
15303
15406
  if (entry.isDirectory()) {
15304
15407
  if (SKIP_DIRS.has(entry.name))
15305
15408
  continue;
15306
- visit(join20(dir, entry.name));
15409
+ visit(join24(dir, entry.name));
15307
15410
  continue;
15308
15411
  }
15309
15412
  if (!entry.isFile())
15310
15413
  continue;
15311
- const file = join20(dir, entry.name);
15414
+ const file = join24(dir, entry.name);
15312
15415
  if (shouldScanRepoFile(file))
15313
15416
  out.push(file);
15314
15417
  }
@@ -15576,7 +15679,7 @@ function stripInlineComment(value) {
15576
15679
  return value.replace(/\s[#;].*$/, "").trim();
15577
15680
  }
15578
15681
  function displayPath(file, root) {
15579
- const home = homedir11();
15682
+ const home = homedir14();
15580
15683
  if (root === home && (file === home || file.startsWith(home + "/")))
15581
15684
  return "~/" + toPosix(relative7(home, file));
15582
15685
  if (isAbsolute5(root) && file.startsWith(root + "/"))
@@ -15630,7 +15733,11 @@ var init_package_manager_guard = __esm(() => {
15630
15733
  // ../events/dist/commander.js
15631
15734
  import { chmod, mkdir, readFile, rename, writeFile } from "fs/promises";
15632
15735
  import { Buffer as Buffer2 } from "buffer";
15736
+ import { existsSync as existsSync2 } from "fs";
15737
+ import { join as join3 } from "path";
15633
15738
  import { existsSync } from "fs";
15739
+ import { homedir as homedir2 } from "os";
15740
+ import { join as join2, resolve } from "path";
15634
15741
  import { homedir } from "os";
15635
15742
  import { join } from "path";
15636
15743
  import { createHmac, timingSafeEqual } from "crypto";
@@ -15736,13 +15843,106 @@ function channelMatchesEvent(channel, event) {
15736
15843
  return true;
15737
15844
  return channel.filters.some((filter) => eventMatchesFilter(event, filter));
15738
15845
  }
15846
+ var KIND_ENV = {
15847
+ config: "HASNA_CONFIG_HOME",
15848
+ data: "HASNA_DATA_HOME",
15849
+ state: "HASNA_STATE_HOME",
15850
+ cache: "HASNA_CACHE_HOME"
15851
+ };
15852
+ var APP_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
15853
+ function assertApp(app) {
15854
+ if (typeof app !== "string" || app.length === 0) {
15855
+ throw new TypeError("paths: app must be a non-empty string");
15856
+ }
15857
+ if (!APP_SLUG_RE.test(app)) {
15858
+ throw new TypeError(`paths: invalid app slug "${app}" \u2014 expected lowercase kebab-case ([a-z0-9]+(-[a-z0-9]+)*)`);
15859
+ }
15860
+ }
15861
+ function envOf(options) {
15862
+ return options.env ?? process.env;
15863
+ }
15864
+ function envValue(options, kind) {
15865
+ const value = envOf(options)[KIND_ENV[kind]];
15866
+ return typeof value === "string" && value.length > 0 ? value : undefined;
15867
+ }
15868
+ function isMacOS(platform) {
15869
+ return platform === "darwin";
15870
+ }
15871
+ function baseDir(kind, options) {
15872
+ const override = envValue(options, kind);
15873
+ if (override)
15874
+ return override;
15875
+ const home = options.home ?? homedir();
15876
+ const platform = options.platform ?? process.platform;
15877
+ if (isMacOS(platform)) {
15878
+ switch (kind) {
15879
+ case "config":
15880
+ case "data":
15881
+ return join(home, "Library", "Application Support", "Hasna");
15882
+ case "cache":
15883
+ return join(home, "Library", "Caches", "Hasna");
15884
+ case "state":
15885
+ return join(home, "Library", "Logs", "Hasna");
15886
+ }
15887
+ }
15888
+ switch (kind) {
15889
+ case "config":
15890
+ return join(home, ".config", "hasna");
15891
+ case "data":
15892
+ return join(home, ".local", "share", "hasna");
15893
+ case "state":
15894
+ return join(home, ".local", "state", "hasna");
15895
+ case "cache":
15896
+ return join(home, ".cache", "hasna");
15897
+ }
15898
+ }
15899
+ function resolvePath(kind, options) {
15900
+ assertApp(options.app);
15901
+ const appSegment = options.internal === true ? join("internal", options.app) : options.app;
15902
+ return join(baseDir(kind, options), appSegment);
15903
+ }
15904
+ function dataDir(options) {
15905
+ return resolvePath("data", options);
15906
+ }
15739
15907
  var HASNA_EVENTS_DIR_ENV = "HASNA_EVENTS_DIR";
15740
15908
  var HASNA_EVENTS_HOME_ENV = "HASNA_EVENTS_HOME";
15909
+ var EVENTS_STORE_SENTINEL_FILE = "events.json";
15910
+ function effectiveHome() {
15911
+ return process.env["HOME"] || process.env["USERPROFILE"] || homedir2();
15912
+ }
15913
+ function legacyHomeDir() {
15914
+ return join2(effectiveHome(), ".hasna", "events");
15915
+ }
15916
+ function resolverHome() {
15917
+ return dataDir({ app: "events", home: effectiveHome() || undefined });
15918
+ }
15919
+ function adoptResolverHome(resolved, env = process.env) {
15920
+ const dataOverride = env.HASNA_DATA_HOME;
15921
+ if (typeof dataOverride === "string" && dataOverride.trim().length > 0)
15922
+ return true;
15923
+ return existsSync(join2(resolved, EVENTS_STORE_SENTINEL_FILE));
15924
+ }
15925
+ function exactEventsHome() {
15926
+ const dir = process.env[HASNA_EVENTS_DIR_ENV];
15927
+ if (dir && dir.trim())
15928
+ return dir.trim();
15929
+ const home = process.env[HASNA_EVENTS_HOME_ENV];
15930
+ if (home && home.trim())
15931
+ return home.trim();
15932
+ return;
15933
+ }
15934
+ function getEventsHome() {
15935
+ const exact = exactEventsHome();
15936
+ if (exact)
15937
+ return resolve(exact);
15938
+ const resolved = resolverHome();
15939
+ return adoptResolverHome(resolved) ? resolve(resolved) : resolve(legacyHomeDir());
15940
+ }
15741
15941
  var LOCAL_JSON_EVENT_CURSOR_PREFIX = "local-json-v1:";
15742
15942
  var DEFAULT_EVENT_PAGE_LIMIT = 100;
15743
15943
  var MAX_EVENT_PAGE_LIMIT = 1000;
15744
15944
  function getEventsDataDir(override) {
15745
- return override || process.env[HASNA_EVENTS_DIR_ENV] || process.env[HASNA_EVENTS_HOME_ENV] || join(homedir(), ".hasna", "events");
15945
+ return override || getEventsHome();
15746
15946
  }
15747
15947
  function getActiveEventsDirEnv() {
15748
15948
  if (process.env[HASNA_EVENTS_DIR_ENV])
@@ -15758,12 +15958,12 @@ class JsonEventsStore {
15758
15958
  channelsPath;
15759
15959
  eventsPath;
15760
15960
  deliveriesPath;
15761
- constructor(dataDir = getEventsDataDir()) {
15762
- this.dataDir = dataDir;
15763
- this.runtime = localJsonRuntime(dataDir);
15764
- this.channelsPath = join(dataDir, "channels.json");
15765
- this.eventsPath = join(dataDir, "events.json");
15766
- this.deliveriesPath = join(dataDir, "deliveries.json");
15961
+ constructor(dataDir2 = getEventsDataDir()) {
15962
+ this.dataDir = dataDir2;
15963
+ this.runtime = localJsonRuntime(dataDir2);
15964
+ this.channelsPath = join3(dataDir2, "channels.json");
15965
+ this.eventsPath = join3(dataDir2, "events.json");
15966
+ this.deliveriesPath = join3(dataDir2, "deliveries.json");
15767
15967
  }
15768
15968
  async init() {
15769
15969
  await mkdir(this.dataDir, { recursive: true, mode: 448 });
@@ -15880,7 +16080,7 @@ class JsonEventsStore {
15880
16080
  };
15881
16081
  }
15882
16082
  async ensureArrayFile(path) {
15883
- if (!existsSync(path)) {
16083
+ if (!existsSync2(path)) {
15884
16084
  await writeFile(path, `[]
15885
16085
  `, { encoding: "utf-8", mode: 384 });
15886
16086
  }
@@ -15910,7 +16110,7 @@ class JsonEventsStore {
15910
16110
  });
15911
16111
  }
15912
16112
  }
15913
- function localJsonRuntime(dataDir = getEventsDataDir()) {
16113
+ function localJsonRuntime(dataDir2 = getEventsDataDir()) {
15914
16114
  return {
15915
16115
  mode: "local-files",
15916
16116
  name: "json-events-store",
@@ -15923,7 +16123,7 @@ function localJsonRuntime(dataDir = getEventsDataDir()) {
15923
16123
  durable: true,
15924
16124
  idempotency: "best-effort-local",
15925
16125
  replayCursors: true,
15926
- description: `Local JSON files in ${dataDir}; no SQLite, Postgres, S3, or AWS runtime is configured by this store.`
16126
+ description: `Local JSON files in ${dataDir2}; no SQLite, Postgres, S3, or AWS runtime is configured by this store.`
15927
16127
  };
15928
16128
  }
15929
16129
  function encodeLocalJsonEventCursor(offset, options = {}) {
@@ -15987,8 +16187,8 @@ function assertCursorFilter(name, cursorValue, optionValue) {
15987
16187
  function findEventByIdentity(events, identity) {
15988
16188
  return events.find((event) => identity.id !== undefined && event.id === identity.id || identity.dedupeKey !== undefined && event.dedupeKey === identity.dedupeKey);
15989
16189
  }
15990
- async function getEventsStatus(dataDir) {
15991
- const store = new JsonEventsStore(dataDir);
16190
+ async function getEventsStatus(dataDir2) {
16191
+ const store = new JsonEventsStore(dataDir2);
15992
16192
  await store.init();
15993
16193
  const [channels, events, deliveries] = await Promise.all([
15994
16194
  store.listChannels(),
@@ -16030,9 +16230,9 @@ async function getEventsStatus(dataDir) {
16030
16230
  }
16031
16231
  };
16032
16232
  }
16033
- function statusFile(dataDir, fileName, records) {
16034
- const path = join(dataDir, fileName);
16035
- return { path, exists: existsSync(path), records };
16233
+ function statusFile(dataDir2, fileName, records) {
16234
+ const path = join3(dataDir2, fileName);
16235
+ return { path, exists: existsSync2(path), records };
16036
16236
  }
16037
16237
  var DEFAULT_SIGNATURE_TOLERANCE_MS = 5 * 60 * 1000;
16038
16238
  function buildSignatureBase(timestamp, body) {
@@ -16371,7 +16571,7 @@ async function pinnedNativeRequest(target, addresses, method, headers, body, sig
16371
16571
  callback(null, entries);
16372
16572
  }
16373
16573
  };
16374
- return new Promise((resolve, reject) => {
16574
+ return new Promise((resolve2, reject) => {
16375
16575
  const request = isHttps ? nodeHttpsRequest(requestOptions, onResponse) : nodeHttpRequest(requestOptions, onResponse);
16376
16576
  const onAbort = () => {
16377
16577
  const error = new Error("The operation was aborted.");
@@ -16398,7 +16598,7 @@ async function pinnedNativeRequest(target, addresses, method, headers, body, sig
16398
16598
  else if (Array.isArray(value))
16399
16599
  headersRecord[name] = value.join(", ");
16400
16600
  }
16401
- resolve(new Response(Buffer.concat(chunks), { status: response.statusCode ?? 200, headers: headersRecord }));
16601
+ resolve2(new Response(Buffer.concat(chunks), { status: response.statusCode ?? 200, headers: headersRecord }));
16402
16602
  });
16403
16603
  }
16404
16604
  });
@@ -16495,7 +16695,7 @@ async function dispatchCommand(event, channel) {
16495
16695
  HASNA_EVENT_SCHEMA_VERSION: event.schemaVersion,
16496
16696
  HASNA_EVENT_JSON: eventJson
16497
16697
  };
16498
- return new Promise((resolve) => {
16698
+ return new Promise((resolve2) => {
16499
16699
  const child = spawn(channel.command.command, channel.command.args ?? [], {
16500
16700
  cwd: channel.command.cwd,
16501
16701
  env,
@@ -16513,7 +16713,7 @@ async function dispatchCommand(event, channel) {
16513
16713
  });
16514
16714
  child.on("error", (error) => {
16515
16715
  clearTimeout(timeout);
16516
- resolve({
16716
+ resolve2({
16517
16717
  attempt: 1,
16518
16718
  status: "failed",
16519
16719
  startedAt,
@@ -16526,7 +16726,7 @@ async function dispatchCommand(event, channel) {
16526
16726
  child.on("close", (code, signal) => {
16527
16727
  clearTimeout(timeout);
16528
16728
  const success = code === 0;
16529
- resolve({
16729
+ resolve2({
16530
16730
  attempt: 1,
16531
16731
  status: success ? "success" : "failed",
16532
16732
  startedAt,
@@ -17179,9 +17379,9 @@ var {
17179
17379
  // src/cli/index.tsx
17180
17380
  init_apply();
17181
17381
  import chalk from "chalk";
17182
- import { existsSync as existsSync20, lstatSync as lstatSync8, readFileSync as readFileSync17, readSync, writeSync } from "fs";
17183
- import { homedir as homedir12 } from "os";
17184
- import { basename as basename8, join as join21, resolve as resolve14 } from "path";
17382
+ import { existsSync as existsSync23, lstatSync as lstatSync8, readFileSync as readFileSync17, readSync, writeSync } from "fs";
17383
+ import { homedir as homedir15 } from "os";
17384
+ import { basename as basename8, join as join25, resolve as resolve15 } from "path";
17185
17385
 
17186
17386
  // src/lib/config-target-identity.ts
17187
17387
  init_apply();
@@ -17227,15 +17427,15 @@ init_redact();
17227
17427
 
17228
17428
  // src/lib/export.ts
17229
17429
  init_config_store();
17230
- import { existsSync as existsSync11, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "fs";
17231
- import { join as join13, resolve as resolve8 } from "path";
17430
+ import { existsSync as existsSync14, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "fs";
17431
+ import { join as join17, resolve as resolve10 } from "path";
17232
17432
  import { tmpdir } from "os";
17233
17433
  async function exportConfigs(outputPath, opts = {}) {
17234
17434
  const store = opts.store ?? resolveConfigStore();
17235
17435
  const configs = await store.listConfigs(opts.filter);
17236
- const absOutput = resolve8(outputPath);
17237
- const tmpDir = join13(tmpdir(), `configs-export-${Date.now()}`);
17238
- const contentsDir = join13(tmpDir, "contents");
17436
+ const absOutput = resolve10(outputPath);
17437
+ const tmpDir = join17(tmpdir(), `configs-export-${Date.now()}`);
17438
+ const contentsDir = join17(tmpDir, "contents");
17239
17439
  try {
17240
17440
  mkdirSync4(contentsDir, { recursive: true });
17241
17441
  const manifest = {
@@ -17243,10 +17443,10 @@ async function exportConfigs(outputPath, opts = {}) {
17243
17443
  exported_at: new Date().toISOString(),
17244
17444
  configs: configs.map(({ content: _content, ...meta }) => meta)
17245
17445
  };
17246
- writeFileSync3(join13(tmpDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
17446
+ writeFileSync3(join17(tmpDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
17247
17447
  for (const config of configs) {
17248
17448
  const fileName = `${config.slug}.${config.format === "text" ? "txt" : config.format}`;
17249
- writeFileSync3(join13(contentsDir, fileName), config.content, "utf-8");
17449
+ writeFileSync3(join17(contentsDir, fileName), config.content, "utf-8");
17250
17450
  }
17251
17451
  const proc = Bun.spawn(["tar", "czf", absOutput, "-C", tmpDir, "."], {
17252
17452
  stdout: "pipe",
@@ -17259,7 +17459,7 @@ async function exportConfigs(outputPath, opts = {}) {
17259
17459
  }
17260
17460
  return { path: absOutput, count: configs.length };
17261
17461
  } finally {
17262
- if (existsSync11(tmpDir)) {
17462
+ if (existsSync14(tmpDir)) {
17263
17463
  rmSync3(tmpDir, { recursive: true, force: true });
17264
17464
  }
17265
17465
  }
@@ -17267,14 +17467,14 @@ async function exportConfigs(outputPath, opts = {}) {
17267
17467
 
17268
17468
  // src/lib/import.ts
17269
17469
  init_config_store();
17270
- import { existsSync as existsSync12, mkdirSync as mkdirSync5, readFileSync as readFileSync9, rmSync as rmSync4 } from "fs";
17271
- import { join as join14, resolve as resolve9 } from "path";
17470
+ import { existsSync as existsSync15, mkdirSync as mkdirSync5, readFileSync as readFileSync9, rmSync as rmSync4 } from "fs";
17471
+ import { join as join18, resolve as resolve11 } from "path";
17272
17472
  import { tmpdir as tmpdir2 } from "os";
17273
17473
  async function importConfigs(bundlePath, opts = {}) {
17274
17474
  const store = opts.store ?? resolveConfigStore();
17275
17475
  const conflict = opts.conflict ?? "skip";
17276
- const absPath = resolve9(bundlePath);
17277
- const tmpDir = join14(tmpdir2(), `configs-import-${Date.now()}`);
17476
+ const absPath = resolve11(bundlePath);
17477
+ const tmpDir = join18(tmpdir2(), `configs-import-${Date.now()}`);
17278
17478
  const result = { created: 0, updated: 0, skipped: 0, errors: [] };
17279
17479
  try {
17280
17480
  mkdirSync5(tmpDir, { recursive: true });
@@ -17287,15 +17487,15 @@ async function importConfigs(bundlePath, opts = {}) {
17287
17487
  const stderr = await new Response(proc.stderr).text();
17288
17488
  throw new Error(`tar extraction failed: ${stderr}`);
17289
17489
  }
17290
- const manifestPath = join14(tmpDir, "manifest.json");
17291
- if (!existsSync12(manifestPath))
17490
+ const manifestPath = join18(tmpDir, "manifest.json");
17491
+ if (!existsSync15(manifestPath))
17292
17492
  throw new Error("Invalid bundle: missing manifest.json");
17293
17493
  const manifest = JSON.parse(readFileSync9(manifestPath, "utf-8"));
17294
17494
  for (const meta of manifest.configs) {
17295
17495
  try {
17296
17496
  const ext = meta.format === "text" ? "txt" : meta.format;
17297
- const contentFile = join14(tmpDir, "contents", `${meta.slug}.${ext}`);
17298
- const content = existsSync12(contentFile) ? readFileSync9(contentFile, "utf-8") : "";
17497
+ const contentFile = join18(tmpDir, "contents", `${meta.slug}.${ext}`);
17498
+ const content = existsSync15(contentFile) ? readFileSync9(contentFile, "utf-8") : "";
17299
17499
  let existing = null;
17300
17500
  try {
17301
17501
  existing = await store.getConfig(meta.slug);
@@ -17329,7 +17529,7 @@ async function importConfigs(bundlePath, opts = {}) {
17329
17529
  }
17330
17530
  return result;
17331
17531
  } finally {
17332
- if (existsSync12(tmpDir)) {
17532
+ if (existsSync15(tmpDir)) {
17333
17533
  rmSync4(tmpDir, { recursive: true, force: true });
17334
17534
  }
17335
17535
  }
@@ -17346,14 +17546,14 @@ init_cursor_authority();
17346
17546
  init_session_authority();
17347
17547
  import { createHash as createHash8, randomUUID as randomUUID7 } from "crypto";
17348
17548
  import {
17349
- existsSync as existsSync13,
17549
+ existsSync as existsSync16,
17350
17550
  lstatSync as lstatSync4,
17351
17551
  mkdirSync as mkdirSync6,
17352
17552
  readFileSync as readFileSync10,
17353
17553
  readdirSync as readdirSync3,
17354
17554
  statSync as statSync6
17355
17555
  } from "fs";
17356
- import { dirname as dirname6, isAbsolute as isAbsolute4, join as join15, parse as parse4, relative as relative5, resolve as resolve10 } from "path";
17556
+ import { dirname as dirname6, isAbsolute as isAbsolute4, join as join19, parse as parse4, relative as relative5, resolve as resolve12 } from "path";
17357
17557
 
17358
17558
  class SessionApplyError extends Error {
17359
17559
  constructor(message) {
@@ -17485,13 +17685,13 @@ function assertClaudeAuthorityStillClear(plan, targetHome, ownedClaudeAuthoritie
17485
17685
  throw new SessionApplyError(`Claude authority changed after planning; refusing to apply: ${summary}`);
17486
17686
  }
17487
17687
  function ensureSessionTargetHome(targetHome) {
17488
- if (!existsSync13(targetHome))
17688
+ if (!existsSync16(targetHome))
17489
17689
  mkdirSync6(targetHome, { recursive: true, mode: 448 });
17490
17690
  assertSafeTargetHome(targetHome);
17491
17691
  }
17492
17692
  function checkSessionRenderDrift(targetHome, manifestPath) {
17493
17693
  const safeTargetHome = assertSafeTargetHome(targetHome);
17494
- const resolvedManifestPath = manifestPath ? resolveManifestRelativePath(relative5(safeTargetHome, resolve10(manifestPath)), safeTargetHome) : resolve10(safeTargetHome, ".hasna", "session-render-manifest.json");
17694
+ const resolvedManifestPath = manifestPath ? resolveManifestRelativePath(relative5(safeTargetHome, resolve12(manifestPath)), safeTargetHome) : resolve12(safeTargetHome, ".hasna", "session-render-manifest.json");
17495
17695
  const checkedAt = new Date().toISOString();
17496
17696
  const previousManifest = readPreviousManifest(resolvedManifestPath);
17497
17697
  if (!previousManifest) {
@@ -17508,7 +17708,7 @@ function checkSessionRenderDrift(targetHome, manifestPath) {
17508
17708
  const drifted = [];
17509
17709
  for (const file of previousManifest.files) {
17510
17710
  const target = resolveManifestRelativePath(file.relativePath, safeTargetHome);
17511
- if (!existsSync13(target)) {
17711
+ if (!existsSync16(target)) {
17512
17712
  missing.push({
17513
17713
  path: target,
17514
17714
  relativePath: file.relativePath,
@@ -17541,7 +17741,7 @@ function checkSessionRenderDrift(targetHome, manifestPath) {
17541
17741
  function restoreSessionRenderSnapshot(snapshotPath, options = {}) {
17542
17742
  const snapshot = readSessionRenderSnapshot(snapshotPath);
17543
17743
  const targetHome = assertSafeTargetHome(snapshot.targetHome);
17544
- const resolvedSnapshotPath = resolve10(snapshotPath);
17744
+ const resolvedSnapshotPath = resolve12(snapshotPath);
17545
17745
  const snapshotRelativePath = relative5(targetHome, resolvedSnapshotPath);
17546
17746
  if (snapshotRelativePath === "" || snapshotRelativePath === ".." || snapshotRelativePath.startsWith("../") || isAbsolute4(snapshotRelativePath)) {
17547
17747
  throw new SessionApplyError("Session snapshot must be stored inside its target home.");
@@ -17659,8 +17859,8 @@ function requiredRestoreHash(file) {
17659
17859
  return file.previousSha256;
17660
17860
  }
17661
17861
  function readSessionRenderSnapshot(snapshotPath) {
17662
- const resolved = resolve10(snapshotPath);
17663
- if (!existsSync13(resolved))
17862
+ const resolved = resolve12(snapshotPath);
17863
+ if (!existsSync16(resolved))
17664
17864
  throw new SessionApplyError(`Session snapshot not found: ${snapshotPath}`);
17665
17865
  const stat = lstatSync4(resolved);
17666
17866
  if (stat.isSymbolicLink() || !stat.isFile()) {
@@ -17740,7 +17940,7 @@ function readSessionRenderSnapshot(snapshotPath) {
17740
17940
  }
17741
17941
  function reconstructPreRollbackLegacyV1Snapshot(snapshot, previousFiles, previousManifestFiles, targetHome, snapshotPath) {
17742
17942
  assertNoNewerSessionSnapshot(snapshotPath, snapshot.createdAt, targetHome);
17743
- const manifestPath = resolve10(snapshot.manifestPath);
17943
+ const manifestPath = resolve12(snapshot.manifestPath);
17744
17944
  const manifestRelativePath = relative5(targetHome, manifestPath).replaceAll("\\", "/");
17745
17945
  resolveSnapshotFilePath(manifestRelativePath, snapshot.manifestPath, targetHome);
17746
17946
  const manifestSha256 = currentSessionFileHash(manifestPath, targetHome);
@@ -17757,7 +17957,7 @@ function reconstructPreRollbackLegacyV1Snapshot(snapshot, previousFiles, previou
17757
17957
  throw new SessionApplyError(`Pre-rollback legacy v1 applied manifest is invalid: ${snapshotPath}`);
17758
17958
  }
17759
17959
  const appliedManifest = parsedManifest;
17760
- if (appliedManifest.schema !== SESSION_RENDER_SCHEMA || appliedManifest.tool !== snapshot.tool || appliedManifest.profile !== snapshot.profile || typeof appliedManifest.targetHome !== "string" || resolve10(appliedManifest.targetHome) !== targetHome || appliedManifest.targetKind !== "session-home" && appliedManifest.targetKind !== "project-root" || !Array.isArray(appliedManifest.files)) {
17960
+ if (appliedManifest.schema !== SESSION_RENDER_SCHEMA || appliedManifest.tool !== snapshot.tool || appliedManifest.profile !== snapshot.profile || typeof appliedManifest.targetHome !== "string" || resolve12(appliedManifest.targetHome) !== targetHome || appliedManifest.targetKind !== "session-home" && appliedManifest.targetKind !== "project-root" || !Array.isArray(appliedManifest.files)) {
17761
17961
  throw new SessionApplyError(`Pre-rollback legacy v1 applied manifest does not match its snapshot: ${snapshotPath}`);
17762
17962
  }
17763
17963
  const afterFiles = [];
@@ -17842,8 +18042,8 @@ function assertNoNewerSessionSnapshot(snapshotPath, createdAt, targetHome) {
17842
18042
  throw new SessionApplyError(`Pre-rollback legacy v1 snapshot has an invalid creation time: ${snapshotPath}`);
17843
18043
  }
17844
18044
  for (const entry of readdirSync3(dirname6(snapshotPath))) {
17845
- const candidatePath = resolve10(dirname6(snapshotPath), entry);
17846
- if (candidatePath === resolve10(snapshotPath) || !entry.endsWith(".json"))
18045
+ const candidatePath = resolve12(dirname6(snapshotPath), entry);
18046
+ if (candidatePath === resolve12(snapshotPath) || !entry.endsWith(".json"))
17847
18047
  continue;
17848
18048
  const candidateStat = lstatSync4(candidatePath);
17849
18049
  if (candidateStat.isSymbolicLink() || !candidateStat.isFile() || candidateStat.size > 32 * 1024 * 1024)
@@ -17851,7 +18051,7 @@ function assertNoNewerSessionSnapshot(snapshotPath, createdAt, targetHome) {
17851
18051
  try {
17852
18052
  const candidate = JSON.parse(readFileSync10(candidatePath, "utf8"));
17853
18053
  const candidateCreatedAtMs = typeof candidate.createdAt === "string" ? Date.parse(candidate.createdAt) : Number.NaN;
17854
- if ((candidate.schema === "hasna.configs.session-render-snapshot/v1" || candidate.schema === "hasna.configs.session-render-snapshot/v2") && typeof candidate.targetHome === "string" && resolve10(candidate.targetHome) === targetHome && Number.isFinite(candidateCreatedAtMs) && candidateCreatedAtMs >= createdAtMs) {
18054
+ if ((candidate.schema === "hasna.configs.session-render-snapshot/v1" || candidate.schema === "hasna.configs.session-render-snapshot/v2") && typeof candidate.targetHome === "string" && resolve12(candidate.targetHome) === targetHome && Number.isFinite(candidateCreatedAtMs) && candidateCreatedAtMs >= createdAtMs) {
17855
18055
  throw new SessionApplyError(`Cannot restore pre-rollback legacy v1 snapshot after a newer session snapshot exists: ${candidatePath}`);
17856
18056
  }
17857
18057
  } catch (error) {
@@ -17920,14 +18120,14 @@ function inferLegacySnapshotAction(file, previousFiles, previousManifestFiles, p
17920
18120
  }
17921
18121
  function resolveSnapshotFilePath(relativePath, recordedPath, targetHome) {
17922
18122
  const path = resolveManifestRelativePath(relativePath, targetHome);
17923
- if (resolve10(recordedPath) !== path) {
18123
+ if (resolve12(recordedPath) !== path) {
17924
18124
  throw new SessionApplyError(`Session snapshot file path mismatch for ${relativePath}`);
17925
18125
  }
17926
18126
  return path;
17927
18127
  }
17928
18128
  function planFileResult(plan, file, targetHome, previousHashes, previousManifest, options) {
17929
18129
  const target = resolvePlannedFilePath(plan, file, targetHome);
17930
- const previousContent = existsSync13(target) ? readFileSync10(target, "utf-8") : null;
18130
+ const previousContent = existsSync16(target) ? readFileSync10(target, "utf-8") : null;
17931
18131
  const previousSha256 = previousContent === null ? null : sha2568(previousContent);
17932
18132
  const previouslyManaged = isPreviouslyManaged(file, previousSha256, previousHashes, previousManifest);
17933
18133
  const changed = previousContent !== file.content;
@@ -18026,7 +18226,7 @@ function planStaleFileResults(plan, targetHome, previousManifest, currentRelativ
18026
18226
  }
18027
18227
  function planStaleFileResult(file, targetHome, options) {
18028
18228
  const target = resolveManifestRelativePath(file.relativePath, targetHome);
18029
- if (!existsSync13(target))
18229
+ if (!existsSync16(target))
18030
18230
  return null;
18031
18231
  const previousContent = readFileSync10(target, "utf-8");
18032
18232
  const previousSha256 = sha2568(previousContent);
@@ -18073,19 +18273,19 @@ function isPreviouslyManaged(file, previousSha256, previousHashes, previousManif
18073
18273
  return previousHashes.get(file.relativePath) === previousSha256;
18074
18274
  }
18075
18275
  function resolvePlannedFilePath(plan, file, targetHome) {
18076
- const target = resolve10(targetHome, ...file.relativePath.split("/"));
18276
+ const target = resolve12(targetHome, ...file.relativePath.split("/"));
18077
18277
  const rel = relative5(targetHome, target);
18078
18278
  if (rel === "" || rel === ".." || rel.startsWith("../") || isAbsolute4(rel)) {
18079
18279
  throw new SessionApplyError(`Session file escapes target home: ${file.relativePath}`);
18080
18280
  }
18081
- if (resolve10(file.path) !== target) {
18281
+ if (resolve12(file.path) !== target) {
18082
18282
  throw new SessionApplyError(`Session file path mismatch for ${file.relativePath}: ${file.path}`);
18083
18283
  }
18084
18284
  assertNoSymlinkSegments2(targetHome, target);
18085
18285
  return target;
18086
18286
  }
18087
18287
  function resolveManifestRelativePath(relativePath, targetHome) {
18088
- const target = resolve10(targetHome, ...relativePath.split(/[\\/]+/));
18288
+ const target = resolve12(targetHome, ...relativePath.split(/[\\/]+/));
18089
18289
  const rel = relative5(targetHome, target);
18090
18290
  if (rel === "" || rel === ".." || rel.startsWith("../") || isAbsolute4(rel)) {
18091
18291
  throw new SessionApplyError(`Session manifest file escapes target home: ${relativePath}`);
@@ -18094,7 +18294,7 @@ function resolveManifestRelativePath(relativePath, targetHome) {
18094
18294
  return target;
18095
18295
  }
18096
18296
  function readPreviousManifest(path) {
18097
- if (!existsSync13(path))
18297
+ if (!existsSync16(path))
18098
18298
  return null;
18099
18299
  try {
18100
18300
  const parsed = JSON.parse(readFileSync10(path, "utf-8"));
@@ -18136,7 +18336,7 @@ function assertExpectedSessionFileHash(path, targetHome, expectedHash) {
18136
18336
  }
18137
18337
  function currentSessionFileHash(path, targetHome) {
18138
18338
  assertNoSymlinkSegments2(targetHome, path);
18139
- if (!existsSync13(path))
18339
+ if (!existsSync16(path))
18140
18340
  return null;
18141
18341
  const stat = lstatSync4(path);
18142
18342
  if (stat.isSymbolicLink() || !stat.isFile()) {
@@ -18151,7 +18351,7 @@ function requiredPreviousHash(result) {
18151
18351
  return result.previousSha256;
18152
18352
  }
18153
18353
  function writeSessionSnapshot(plan, targetHome, manifestPath, results, previousManifest, coordination, allowPortableFallback, forcePortableFileOps) {
18154
- const existingFiles = results.filter((result) => result.action === "update" || result.action === "delete").filter((result) => existsSync13(result.path)).map((result) => {
18354
+ const existingFiles = results.filter((result) => result.action === "update" || result.action === "delete").filter((result) => existsSync16(result.path)).map((result) => {
18155
18355
  const content = readFileSync10(result.path, "utf-8");
18156
18356
  return {
18157
18357
  path: result.path,
@@ -18170,7 +18370,7 @@ function writeSessionSnapshot(plan, targetHome, manifestPath, results, previousM
18170
18370
  };
18171
18371
  }
18172
18372
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
18173
- const snapshotPath = resolve10(targetHome, ".hasna", "session-render-snapshots", `${timestamp}-${randomUUID7()}.json`);
18373
+ const snapshotPath = resolve12(targetHome, ".hasna", "session-render-snapshots", `${timestamp}-${randomUUID7()}.json`);
18174
18374
  const afterFiles = results.map((result) => {
18175
18375
  if (result.action === "conflict") {
18176
18376
  throw new SessionApplyError(`Cannot snapshot unresolved conflict: ${result.relativePath}`);
@@ -18218,12 +18418,12 @@ function writeSessionSnapshot(plan, targetHome, manifestPath, results, previousM
18218
18418
  function assertSafeTargetHome(targetHome) {
18219
18419
  if (!isAbsolute4(targetHome))
18220
18420
  throw new SessionApplyError(`Session target home must be absolute: ${targetHome}`);
18221
- const normalized = resolve10(targetHome);
18421
+ const normalized = resolve12(targetHome);
18222
18422
  if (normalized === parse4(normalized).root) {
18223
18423
  throw new SessionApplyError(`Session target home cannot be the filesystem root: ${targetHome}`);
18224
18424
  }
18225
18425
  assertNoSymlinkAncestors2(normalized);
18226
- if (existsSync13(normalized) && lstatSync4(normalized).isSymbolicLink()) {
18426
+ if (existsSync16(normalized) && lstatSync4(normalized).isSymbolicLink()) {
18227
18427
  throw new SessionApplyError(`Session target home cannot be a symlink: ${normalized}`);
18228
18428
  }
18229
18429
  return normalized;
@@ -18233,20 +18433,20 @@ function assertNoSymlinkSegments2(root, target) {
18233
18433
  const rel = relative5(root, target);
18234
18434
  let current = root;
18235
18435
  for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
18236
- current = join15(current, segment);
18237
- if (existsSync13(current) && lstatSync4(current).isSymbolicLink()) {
18436
+ current = join19(current, segment);
18437
+ if (existsSync16(current) && lstatSync4(current).isSymbolicLink()) {
18238
18438
  throw new SessionApplyError(`Session apply path uses a symlink: ${current}`);
18239
18439
  }
18240
18440
  }
18241
18441
  }
18242
18442
  function assertNoSymlinkAncestors2(path) {
18243
- const normalized = resolve10(path);
18443
+ const normalized = resolve12(path);
18244
18444
  const parsed = parse4(normalized);
18245
18445
  let current = parsed.root;
18246
18446
  const rel = relative5(parsed.root, normalized);
18247
18447
  for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
18248
- current = join15(current, segment);
18249
- if (!existsSync13(current))
18448
+ current = join19(current, segment);
18449
+ if (!existsSync16(current))
18250
18450
  return;
18251
18451
  if (lstatSync4(current).isSymbolicLink()) {
18252
18452
  throw new SessionApplyError(`Session apply path uses a symlink ancestor: ${current}`);
@@ -18295,10 +18495,11 @@ function formatGlobalSourceCoverageWarnings(result) {
18295
18495
  }
18296
18496
 
18297
18497
  // src/lib/station-profile.ts
18498
+ init_raw_store_root();
18298
18499
  import { spawnSync } from "child_process";
18299
- import { existsSync as existsSync14, lstatSync as lstatSync5, mkdirSync as mkdirSync7, readFileSync as readFileSync11, readdirSync as readdirSync4, writeFileSync as writeFileSync4 } from "fs";
18300
- import { arch as osArch, homedir as homedir9, hostname as osHostname, platform as osPlatform, userInfo as osUserInfo } from "os";
18301
- import { dirname as dirname7, join as join16, resolve as resolve11 } from "path";
18500
+ import { existsSync as existsSync17, lstatSync as lstatSync5, mkdirSync as mkdirSync7, readFileSync as readFileSync11, readdirSync as readdirSync4, writeFileSync as writeFileSync4 } from "fs";
18501
+ import { arch as osArch, homedir as homedir12, hostname as osHostname, platform as osPlatform, userInfo as osUserInfo } from "os";
18502
+ import { dirname as dirname7, join as join20 } from "path";
18302
18503
  var STATION_PROFILE_CACHE_FILENAME = "station-profile.md";
18303
18504
  var STATION_PROFILE_SOURCE_ID = "station-profile";
18304
18505
  var STATION_PROFILE_LAYER = "machine";
@@ -18308,22 +18509,21 @@ var STATION_PROFILE_FULL_NAMES_MAX = 6;
18308
18509
  var STATION_PROFILE_PRIMARY_SCOPE = "@hasna";
18309
18510
  var MACHINES_MANIFEST_PATH_ENV = "HASNA_MACHINES_MANIFEST_PATH";
18310
18511
  var BUN_INSTALL_ENV = "BUN_INSTALL";
18311
- function homeDir2(env = process.env) {
18312
- return env["HOME"] || env["USERPROFILE"] || homedir9();
18512
+ function homeDir3(env = process.env) {
18513
+ return env["HOME"] || env["USERPROFILE"] || homedir12();
18313
18514
  }
18314
18515
  function getStationProfileCachePath(env = process.env) {
18315
- const root = env["HASNA_CONFIGS_HOME"] || join16(homeDir2(env), ".hasna", "instructions");
18316
- return join16(resolve11(root), STATION_PROFILE_CACHE_FILENAME);
18516
+ return join20(getRawStoreRoot(env), STATION_PROFILE_CACHE_FILENAME);
18317
18517
  }
18318
18518
  function getMachinesManifestPath(env = process.env) {
18319
- return env[MACHINES_MANIFEST_PATH_ENV] || join16(homeDir2(env), ".hasna", "machines", "machines.json");
18519
+ return env[MACHINES_MANIFEST_PATH_ENV] || join20(homeDir3(env), ".hasna", "machines", "machines.json");
18320
18520
  }
18321
18521
  function getBunGlobalModulesDir(env = process.env) {
18322
- return join16(env[BUN_INSTALL_ENV] || join16(homeDir2(env), ".bun"), "install", "global", "node_modules");
18522
+ return join20(env[BUN_INSTALL_ENV] || join20(homeDir3(env), ".bun"), "install", "global", "node_modules");
18323
18523
  }
18324
18524
  function readMachinesManifest(path) {
18325
18525
  try {
18326
- if (!existsSync14(path))
18526
+ if (!existsSync17(path))
18327
18527
  return null;
18328
18528
  const parsed = JSON.parse(readFileSync11(path, "utf8"));
18329
18529
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
@@ -18379,9 +18579,9 @@ function probeMachineStatus(machineId) {
18379
18579
  function resolveStationProfileMachine(env = process.env, options = {}) {
18380
18580
  const hostname2 = osHostname();
18381
18581
  const record = findLocalManifestMachine(readMachinesManifest(getMachinesManifestPath(env)), hostname2);
18382
- const home = homeDir2(env);
18582
+ const home = homeDir3(env);
18383
18583
  const platform = stringField(record, "platform") ?? osPlatform();
18384
- const workspacePath = stringField(record, "workspacePath") ?? join16(home, platform === "darwin" ? "Workspace" : "workspace");
18584
+ const workspacePath = stringField(record, "workspacePath") ?? join20(home, platform === "darwin" ? "Workspace" : "workspace");
18385
18585
  const machine = {
18386
18586
  id: stringField(record, "id") ?? hostname2,
18387
18587
  hostname: stringField(record, "hostname") ?? hostname2,
@@ -18398,9 +18598,9 @@ function resolveStationProfileMachine(env = process.env, options = {}) {
18398
18598
  return machine;
18399
18599
  }
18400
18600
  function scopedPackageNames(modulesDir, scope) {
18401
- const scopeDir = join16(modulesDir, scope);
18601
+ const scopeDir = join20(modulesDir, scope);
18402
18602
  try {
18403
- if (!existsSync14(scopeDir))
18603
+ if (!existsSync17(scopeDir))
18404
18604
  return null;
18405
18605
  return readdirNames(scopeDir).sort();
18406
18606
  } catch {
@@ -18410,7 +18610,7 @@ function scopedPackageNames(modulesDir, scope) {
18410
18610
  function readdirNames(dir) {
18411
18611
  return readdirSync4(dir).filter((name) => {
18412
18612
  try {
18413
- return lstatSync5(join16(dir, name)).isDirectory();
18613
+ return lstatSync5(join20(dir, name)).isDirectory();
18414
18614
  } catch {
18415
18615
  return false;
18416
18616
  }
@@ -18420,7 +18620,7 @@ function resolveStationProfilePackages(env = process.env) {
18420
18620
  const modulesDir = getBunGlobalModulesDir(env);
18421
18621
  let scopeDirs;
18422
18622
  try {
18423
- if (!existsSync14(modulesDir))
18623
+ if (!existsSync17(modulesDir))
18424
18624
  return null;
18425
18625
  scopeDirs = readdirNames(modulesDir).filter((name) => name.startsWith("@") && name.toLowerCase().includes("hasna"));
18426
18626
  } catch {
@@ -18495,7 +18695,7 @@ function refreshStationProfile(options = {}) {
18495
18695
  const path = getStationProfileCachePath(env);
18496
18696
  const generatedAt = new Date().toISOString();
18497
18697
  if (!options.dryRun) {
18498
- const existing = existsSync14(path) ? readFileSync11(path, "utf8") : null;
18698
+ const existing = existsSync17(path) ? readFileSync11(path, "utf8") : null;
18499
18699
  if (existing !== content) {
18500
18700
  mkdirSync7(dirname7(path), { recursive: true });
18501
18701
  writeFileSync4(path, content, "utf8");
@@ -18514,7 +18714,7 @@ function refreshStationProfile(options = {}) {
18514
18714
  function readStationProfile(env = process.env) {
18515
18715
  const path = getStationProfileCachePath(env);
18516
18716
  try {
18517
- if (!existsSync14(path))
18717
+ if (!existsSync17(path))
18518
18718
  return null;
18519
18719
  return readFileSync11(path, "utf8");
18520
18720
  } catch {
@@ -18853,7 +19053,7 @@ init_codewith_shared_todos_storage_standard();
18853
19053
  import { createHash as createHash9 } from "crypto";
18854
19054
  import { spawnSync as spawnSync2 } from "child_process";
18855
19055
  import {
18856
- existsSync as existsSync15,
19056
+ existsSync as existsSync18,
18857
19057
  lstatSync as lstatSync6,
18858
19058
  mkdirSync as mkdirSync8,
18859
19059
  readFileSync as readFileSync12,
@@ -18861,8 +19061,8 @@ import {
18861
19061
  rmSync as rmSync5,
18862
19062
  writeFileSync as writeFileSync5
18863
19063
  } from "fs";
18864
- import { homedir as homedir10 } from "os";
18865
- import { dirname as dirname8, join as join17, parse as parse5, relative as relative6, resolve as resolve12 } from "path";
19064
+ import { homedir as homedir13 } from "os";
19065
+ import { dirname as dirname8, join as join21, parse as parse5, relative as relative6, resolve as resolve13 } from "path";
18866
19066
  var INBOX_CONVERSATIONS_MINIMUM_VERSION = "0.5.28";
18867
19067
  var INBOX_SKILL_MARKERS = [
18868
19068
  [".claude", "skills", "inbox", "SKILL.md"],
@@ -18883,13 +19083,13 @@ function lstatOrNull(path) {
18883
19083
  }
18884
19084
  }
18885
19085
  function findSymlinkedAncestor(path) {
18886
- const normalized = resolve12(path);
19086
+ const normalized = resolve13(path);
18887
19087
  const parsed = parse5(normalized);
18888
19088
  let current = parsed.root;
18889
19089
  const rel = relative6(parsed.root, normalized);
18890
19090
  for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
18891
- current = join17(current, segment);
18892
- if (!existsSync15(current))
19091
+ current = join21(current, segment);
19092
+ if (!existsSync18(current))
18893
19093
  return null;
18894
19094
  if (lstatSync6(current).isSymbolicLink())
18895
19095
  return current;
@@ -18906,11 +19106,11 @@ function packagedInboxSkillPath(explicitPath) {
18906
19106
  if (explicitPath)
18907
19107
  return explicitPath;
18908
19108
  const candidates = [
18909
- join17(import.meta.dir, "..", "..", "assets", "skills", "inbox", "SKILL.md"),
18910
- join17(import.meta.dir, "..", "assets", "skills", "inbox", "SKILL.md"),
18911
- join17(process.cwd(), "assets", "skills", "inbox", "SKILL.md")
19109
+ join21(import.meta.dir, "..", "..", "assets", "skills", "inbox", "SKILL.md"),
19110
+ join21(import.meta.dir, "..", "assets", "skills", "inbox", "SKILL.md"),
19111
+ join21(process.cwd(), "assets", "skills", "inbox", "SKILL.md")
18912
19112
  ];
18913
- const found = candidates.find((candidate) => existsSync15(candidate));
19113
+ const found = candidates.find((candidate) => existsSync18(candidate));
18914
19114
  if (!found) {
18915
19115
  throw new Error(`packaged inbox skill contract is missing (checked ${candidates.length} package-relative locations)`);
18916
19116
  }
@@ -18959,8 +19159,8 @@ function compareVersions(left, right) {
18959
19159
  }
18960
19160
  return 0;
18961
19161
  }
18962
- function inspectSkillMarkers(homeDir3) {
18963
- return INBOX_SKILL_MARKERS.map((parts) => join17(homeDir3, ...parts)).map((path) => {
19162
+ function inspectSkillMarkers(homeDir4) {
19163
+ return INBOX_SKILL_MARKERS.map((parts) => join21(homeDir4, ...parts)).map((path) => {
18964
19164
  const stat = lstatOrNull(path);
18965
19165
  if (!stat)
18966
19166
  return null;
@@ -18976,9 +19176,9 @@ function inspectSkillMarkers(homeDir3) {
18976
19176
  }).filter((snapshot) => snapshot !== null);
18977
19177
  }
18978
19178
  function inspectInbox(options) {
18979
- const homeDir3 = options.homeDir ?? homedir10();
19179
+ const homeDir4 = options.homeDir ?? homedir13();
18980
19180
  const runtimeCommand = options.conversationsCommand ?? "conversations";
18981
- const snapshots = inspectSkillMarkers(homeDir3);
19181
+ const snapshots = inspectSkillMarkers(homeDir4);
18982
19182
  const skillPresent = snapshots.length > 0;
18983
19183
  let canonicalContent = null;
18984
19184
  let canonicalSha256 = null;
@@ -19253,11 +19453,11 @@ init_project_context();
19253
19453
  init_config_store();
19254
19454
  init_apply();
19255
19455
  init_config_agents();
19256
- import { existsSync as existsSync17, readFileSync as readFileSync14 } from "fs";
19456
+ import { existsSync as existsSync20, readFileSync as readFileSync14 } from "fs";
19257
19457
 
19258
19458
  // src/lib/package-version.ts
19259
- import { existsSync as existsSync16, readFileSync as readFileSync13 } from "fs";
19260
- import { dirname as dirname9, join as join18 } from "path";
19459
+ import { existsSync as existsSync19, readFileSync as readFileSync13 } from "fs";
19460
+ import { dirname as dirname9, join as join22 } from "path";
19261
19461
  import { fileURLToPath } from "url";
19262
19462
  var cached = null;
19263
19463
  function getPackageVersion() {
@@ -19266,8 +19466,8 @@ function getPackageVersion() {
19266
19466
  try {
19267
19467
  let dir = dirname9(fileURLToPath(import.meta.url));
19268
19468
  for (let i = 0;i < 8; i++) {
19269
- const pkgPath = join18(dir, "package.json");
19270
- if (existsSync16(pkgPath)) {
19469
+ const pkgPath = join22(dir, "package.json");
19470
+ if (existsSync19(pkgPath)) {
19271
19471
  const pkg = JSON.parse(readFileSync13(pkgPath, "utf8"));
19272
19472
  if (pkg.name === "@hasna/instructions" && pkg.version) {
19273
19473
  cached = pkg.version;
@@ -19331,7 +19531,7 @@ async function getConfigsStatus(store = resolveConfigStore(), options = {}) {
19331
19531
  continue;
19332
19532
  knownTargets += 1;
19333
19533
  const targetPath = expandPath(config.target_path);
19334
- if (!existsSync17(targetPath)) {
19534
+ if (!existsSync20(targetPath)) {
19335
19535
  missingTargets += 1;
19336
19536
  continue;
19337
19537
  }
@@ -19431,8 +19631,8 @@ init_config_store();
19431
19631
 
19432
19632
  // src/lib/provider-context.ts
19433
19633
  import { createHash as createHash10 } from "crypto";
19434
- import { existsSync as existsSync18, mkdirSync as mkdirSync9, readFileSync as readFileSync15, writeFileSync as writeFileSync6 } from "fs";
19435
- import { join as join19 } from "path";
19634
+ import { existsSync as existsSync21, mkdirSync as mkdirSync9, readFileSync as readFileSync15, writeFileSync as writeFileSync6 } from "fs";
19635
+ import { join as join23 } from "path";
19436
19636
  var PROVIDER_CONTEXT_DIR = ".hasna/provider-context";
19437
19637
  var PROVIDER_CONTEXT_MANIFEST = "manifest.json";
19438
19638
  var PROVIDER_CONTEXT_SCHEMA = "hasna.instructions.provider-context/v1";
@@ -19577,17 +19777,17 @@ function resolveAndRenderProviderContext(opts) {
19577
19777
  const recordedEndpoint = originAccepted ? `${opts.origin.host}${opts.origin.pathPrefix || ""}` : null;
19578
19778
  const reason = entry === null && opts.rawEndpoint ? originAccepted ? `endpoint "${recordedEndpoint}" is not in the provider-context registry; using the invariant fragment` : "endpoint rejected (embedded credentials or unparseable); using the invariant fragment" : null;
19579
19779
  const content = renderProviderFragment(entry);
19580
- const dir = join19(opts.homeDir, PROVIDER_CONTEXT_DIR);
19581
- if (!existsSync18(dir))
19780
+ const dir = join23(opts.homeDir, PROVIDER_CONTEXT_DIR);
19781
+ if (!existsSync21(dir))
19582
19782
  mkdirSync9(dir, { recursive: true });
19583
19783
  const filename = `${entry ? entry.key : "invariant"}.md`;
19584
- const fragmentPath2 = join19(dir, filename);
19784
+ const fragmentPath2 = join23(dir, filename);
19585
19785
  const fragmentSha256 = sha25610(content);
19586
19786
  writeFileSync6(fragmentPath2, content, "utf8");
19587
- const manifestPath = join19(dir, PROVIDER_CONTEXT_MANIFEST);
19787
+ const manifestPath = join23(dir, PROVIDER_CONTEXT_MANIFEST);
19588
19788
  let manifest = { schema: PROVIDER_CONTEXT_SCHEMA, fragments: {} };
19589
19789
  try {
19590
- if (existsSync18(manifestPath)) {
19790
+ if (existsSync21(manifestPath)) {
19591
19791
  const parsed = JSON.parse(readFileSync15(manifestPath, "utf8"));
19592
19792
  if (parsed && typeof parsed === "object")
19593
19793
  manifest = parsed;
@@ -19731,7 +19931,7 @@ function parseSessionSource(value, order) {
19731
19931
  if (!path)
19732
19932
  throw new Error(`Invalid --source "${value}" (expected path or id=path)`);
19733
19933
  const absPath = resolveSessionPath(path);
19734
- if (!existsSync20(absPath))
19934
+ if (!existsSync23(absPath))
19735
19935
  throw new Error(`Instruction source file not found: ${absPath}`);
19736
19936
  const content = readSessionInstructionSourceFile(absPath);
19737
19937
  const source = sourceFromFilePath(absPath, content, order);
@@ -19812,7 +20012,7 @@ async function collectSessionSources(opts, tool, store) {
19812
20012
  }
19813
20013
  for (const value of opts.identityExport ?? []) {
19814
20014
  const path = resolveSessionPath(value);
19815
- if (!existsSync20(path))
20015
+ if (!existsSync23(path))
19816
20016
  throw new Error(`Identity instruction export not found: ${path}`);
19817
20017
  const parsed = JSON.parse(readFileSync17(path, "utf-8"));
19818
20018
  sources.push(...sourcesFromIdentityExport(parsed, { path, tool, orderOffset: sources.length }));
@@ -19946,7 +20146,7 @@ function readProjectContextBundleOption(value, allowMissing = false) {
19946
20146
  if (value === "-")
19947
20147
  return { json: readBoundedProjectContextStdin() };
19948
20148
  const path = resolveSessionPath(value);
19949
- if (!existsSync20(path)) {
20149
+ if (!existsSync23(path)) {
19950
20150
  if (allowMissing)
19951
20151
  return {};
19952
20152
  throw new ProjectContextError("PROJECT_CONTEXT_INPUT_MISSING", `bundle file not found: ${path}`);
@@ -20117,8 +20317,8 @@ program.command("tag <id>").description("Add or remove tags on a stored config (
20117
20317
  console.log(chalk.green("\u2713") + ` Tags on ${chalk.bold(updated.name)} ${chalk.dim(`(${updated.slug})`)}: ${nextTags.join(", ") || chalk.dim("(none)")}`);
20118
20318
  });
20119
20319
  program.command("add <path>").description("Ingest a file into the config DB").option("-n, --name <name>", "config name (defaults to filename)").option("-c, --category <cat>", "category override").option("-a, --agent <agent>", "agent override").option("-k, --kind <kind>", "kind: file|reference", "file").option("--template", "mark as template (has {{VAR}} placeholders)").option("--update", "if a config already owns this path, update that row in place instead of refusing").action(async (filePath, opts) => {
20120
- const abs = resolve14(filePath);
20121
- if (!existsSync20(abs)) {
20320
+ const abs = resolve15(filePath);
20321
+ if (!existsSync23(abs)) {
20122
20322
  console.error(chalk.red(`File not found: ${abs}`));
20123
20323
  process.exit(1);
20124
20324
  }
@@ -20126,7 +20326,7 @@ program.command("add <path>").description("Ingest a file into the config DB").op
20126
20326
  const storedFmt = detectFormat(abs);
20127
20327
  const fmt = redactFormatForTarget(abs, storedFmt);
20128
20328
  const { content, redacted, isTemplate: isTemplate2 } = redactContent(rawContent, fmt);
20129
- const targetPath = abs.startsWith(homedir12()) ? abs.replace(homedir12(), "~") : abs;
20329
+ const targetPath = abs.startsWith(homedir15()) ? abs.replace(homedir15(), "~") : abs;
20130
20330
  const name = opts.name || filePath.split("/").pop();
20131
20331
  const store = resolveConfigStore();
20132
20332
  const allConfigs = await store.listConfigs();
@@ -20301,7 +20501,7 @@ program.command("sync").description("Sync known AI coding configs from disk into
20301
20501
  for (const entry of entries) {
20302
20502
  if (!entry.isDirectory())
20303
20503
  continue;
20304
- const projDir = join21(absDir, entry.name);
20504
+ const projDir = join25(absDir, entry.name);
20305
20505
  const hasAgentConfig = [
20306
20506
  "CLAUDE.md",
20307
20507
  ".mcp.json",
@@ -20314,7 +20514,7 @@ program.command("sync").description("Sync known AI coding configs from disk into
20314
20514
  ".aicopilot",
20315
20515
  ".cursor",
20316
20516
  ".agents"
20317
- ].some((marker) => existsSync20(join21(projDir, marker)));
20517
+ ].some((marker) => existsSync23(join25(projDir, marker)));
20318
20518
  if (!hasAgentConfig)
20319
20519
  continue;
20320
20520
  const result2 = await syncProject({ projectDir: projDir, dryRun: opts.dryRun, store });
@@ -20365,7 +20565,7 @@ program.command("import <file>").description("Import configs from a tar.gz bundl
20365
20565
  });
20366
20566
  program.command("whoami").description("Show setup summary").action(async () => {
20367
20567
  const store = resolveConfigStore();
20368
- const dbPath = isApiTransport() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1` : process.env["HASNA_INSTRUCTIONS_DB_PATH"] || join21(getRawStoreRoot(), "instructions.db");
20568
+ const dbPath = isApiTransport() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1` : process.env["HASNA_INSTRUCTIONS_DB_PATH"] || join25(getRawStoreRoot(), "instructions.db");
20369
20569
  const stats = await store.getConfigStats();
20370
20570
  console.log(chalk.bold("@hasna/instructions") + chalk.dim(" v" + pkg.version));
20371
20571
  console.log(chalk.cyan(isApiTransport() ? "API:" : "DB:") + " " + dbPath);
@@ -21244,7 +21444,7 @@ mcpCmd.command("install").alias("add").description("Install configs MCP server i
21244
21444
  } else if (target === "codex") {
21245
21445
  const { appendFileSync, existsSync: ex } = await import("fs");
21246
21446
  const { join: j } = await import("path");
21247
- const configPath = j(homedir12(), ".codex", "config.toml");
21447
+ const configPath = j(homedir15(), ".codex", "config.toml");
21248
21448
  const block = `
21249
21449
  [mcp_servers.configs]
21250
21450
  command = "${mcpBinary}"
@@ -21262,7 +21462,7 @@ args = []
21262
21462
  } else if (target === "antigravity") {
21263
21463
  const { mkdirSync: md, readFileSync: rf, writeFileSync: wf, existsSync: ex } = await import("fs");
21264
21464
  const { dirname: dn, join: j } = await import("path");
21265
- const configPath = j(homedir12(), ".gemini", "config", "mcp_config.json");
21465
+ const configPath = j(homedir15(), ".gemini", "config", "mcp_config.json");
21266
21466
  let settings = {};
21267
21467
  if (ex(configPath)) {
21268
21468
  try {
@@ -21346,7 +21546,7 @@ DB stats:`));
21346
21546
  if (count > 0)
21347
21547
  console.log(` ${key.padEnd(18)} ${count}`);
21348
21548
  }
21349
- const location = isApiTransport() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1` : process.env["HASNA_INSTRUCTIONS_DB_PATH"] || join21(getRawStoreRoot(), "instructions.db");
21549
+ const location = isApiTransport() ? `${process.env["HASNA_INSTRUCTIONS_API_URL"]}/v1` : process.env["HASNA_INSTRUCTIONS_DB_PATH"] || join25(getRawStoreRoot(), "instructions.db");
21350
21550
  console.log(chalk.dim(`
21351
21551
  ${isApiTransport() ? "API" : "DB"}: ${location}`));
21352
21552
  });
@@ -21407,10 +21607,10 @@ managedSkillsCmd.command("apply").option("--dry-run", "preview without writing")
21407
21607
  });
21408
21608
  program.command("backup").description("Export configs to a timestamped backup file").action(async () => {
21409
21609
  const { mkdirSync: mk } = await import("fs");
21410
- const backupDir = join21(getRawStoreRoot(), "backups");
21610
+ const backupDir = join25(getRawStoreRoot(), "backups");
21411
21611
  mk(backupDir, { recursive: true });
21412
21612
  const ts = new Date().toISOString().replace(/[:.]/g, "-").replace("T", "-").slice(0, 19);
21413
- const outPath = join21(backupDir, `configs-${ts}.tar.gz`);
21613
+ const outPath = join25(backupDir, `configs-${ts}.tar.gz`);
21414
21614
  const result = await exportConfigs(outPath, { store: resolveConfigStore() });
21415
21615
  const { statSync: st } = await import("fs");
21416
21616
  const size = st(outPath).size;
@@ -21438,9 +21638,9 @@ program.command("doctor").description("Validate configs: syntax, permissions, mi
21438
21638
  console.log(chalk.cyan("Known files on disk:"));
21439
21639
  for (const k of KNOWN_CONFIGS) {
21440
21640
  if (k.rulesDir) {
21441
- existsSync20(expandPath(k.rulesDir)) ? pass(`${k.rulesDir}/ exists`) : k.optional ? skip(`${k.rulesDir}/ (optional)`) : fail2(`${k.rulesDir}/ not found`);
21641
+ existsSync23(expandPath(k.rulesDir)) ? pass(`${k.rulesDir}/ exists`) : k.optional ? skip(`${k.rulesDir}/ (optional)`) : fail2(`${k.rulesDir}/ not found`);
21442
21642
  } else {
21443
- existsSync20(expandPath(k.path)) ? pass(k.path) : k.optional ? skip(`${k.path} (optional)`) : fail2(`${k.path} not found`);
21643
+ existsSync23(expandPath(k.path)) ? pass(k.path) : k.optional ? skip(`${k.path} (optional)`) : fail2(`${k.path} not found`);
21444
21644
  }
21445
21645
  }
21446
21646
  const allConfigs = await store.listConfigs();
@@ -21594,16 +21794,16 @@ program.command("watch").description("Watch known config files for changes and a
21594
21794
  for (const k of KNOWN_CONFIGS) {
21595
21795
  if (k.rulesDir) {
21596
21796
  const absDir = expandPath2(k.rulesDir);
21597
- if (!existsSync20(absDir))
21797
+ if (!existsSync23(absDir))
21598
21798
  continue;
21599
21799
  const { readdirSync: readdirSync6 } = await import("fs");
21600
21800
  for (const f of readdirSync6(absDir).filter((f2) => f2.endsWith(".md"))) {
21601
- const abs = join21(absDir, f);
21801
+ const abs = join25(absDir, f);
21602
21802
  mtimes.set(abs, st(abs).mtimeMs);
21603
21803
  }
21604
21804
  } else {
21605
21805
  const abs = expandPath2(k.path);
21606
- if (existsSync20(abs))
21806
+ if (existsSync23(abs))
21607
21807
  mtimes.set(abs, st(abs).mtimeMs);
21608
21808
  }
21609
21809
  }
@@ -21611,7 +21811,7 @@ program.command("watch").description("Watch known config files for changes and a
21611
21811
  const tick = async () => {
21612
21812
  let changed = 0;
21613
21813
  for (const [abs, oldMtime] of mtimes) {
21614
- if (!existsSync20(abs))
21814
+ if (!existsSync23(abs))
21615
21815
  continue;
21616
21816
  const newMtime = st(abs).mtimeMs;
21617
21817
  if (newMtime !== oldMtime) {
@@ -21623,10 +21823,10 @@ program.command("watch").description("Watch known config files for changes and a
21623
21823
  for (const k of KNOWN_CONFIGS) {
21624
21824
  if (k.rulesDir) {
21625
21825
  const absDir = expandPath2(k.rulesDir);
21626
- if (!existsSync20(absDir))
21826
+ if (!existsSync23(absDir))
21627
21827
  continue;
21628
21828
  for (const f of rd(absDir).filter((f2) => f2.endsWith(".md"))) {
21629
- const abs = join21(absDir, f);
21829
+ const abs = join25(absDir, f);
21630
21830
  if (!mtimes.has(abs)) {
21631
21831
  mtimes.set(abs, st(abs).mtimeMs);
21632
21832
  changed++;
@@ -21634,7 +21834,7 @@ program.command("watch").description("Watch known config files for changes and a
21634
21834
  }
21635
21835
  } else {
21636
21836
  const abs = expandPath2(k.path);
21637
- if (existsSync20(abs) && !mtimes.has(abs)) {
21837
+ if (existsSync23(abs) && !mtimes.has(abs)) {
21638
21838
  mtimes.set(abs, st(abs).mtimeMs);
21639
21839
  changed++;
21640
21840
  }
@@ -21662,7 +21862,7 @@ program.command("report").description("Summary of stored configs, drift, and eco
21662
21862
  if (!c.target_path)
21663
21863
  continue;
21664
21864
  const abs = expandPath(c.target_path);
21665
- if (!existsSync20(abs)) {
21865
+ if (!existsSync23(abs)) {
21666
21866
  missing++;
21667
21867
  continue;
21668
21868
  }
@@ -21733,7 +21933,7 @@ program.command("clean").description("Remove configs from DB whose target files
21733
21933
  if (!c.target_path)
21734
21934
  continue;
21735
21935
  const abs = expandPath(c.target_path);
21736
- if (!existsSync20(abs)) {
21936
+ if (!existsSync23(abs)) {
21737
21937
  if (printed < maxPrinted) {
21738
21938
  if (opts.dryRun) {
21739
21939
  console.log(chalk.yellow(" would remove:") + ` ${c.slug} ${chalk.dim(`(${truncateMiddle(c.target_path, 88)})`)}`);
@@ -21879,13 +22079,13 @@ providerContextCmd.command("resolve").description("Resolve the endpoint to a pro
21879
22079
  try {
21880
22080
  const rawEndpoint = opts.endpoint ?? process.env["ANTHROPIC_BASE_URL"] ?? "";
21881
22081
  const rawModel = opts.model ?? process.env["ANTHROPIC_MODEL"] ?? "";
21882
- const homeDir3 = opts.home ?? homedir12();
22082
+ const homeDir4 = opts.home ?? homedir15();
21883
22083
  const origin = normalizeEndpointOrigin(rawEndpoint);
21884
22084
  const resolution = resolveAndRenderProviderContext({
21885
22085
  origin,
21886
22086
  rawEndpoint,
21887
22087
  rawModel,
21888
- homeDir: homeDir3
22088
+ homeDir: homeDir4
21889
22089
  });
21890
22090
  if (opts.json) {
21891
22091
  printJson({