@hasna/instructions 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -103,8 +103,8 @@ import { randomUUID as randomUUID3 } from "crypto";
103
103
 
104
104
  // src/db/database.ts
105
105
  import { Database } from "bun:sqlite";
106
- import { existsSync, mkdirSync, rmSync } from "fs";
107
- import { join as join2 } from "path";
106
+ import { existsSync as existsSync2, mkdirSync, rmSync } from "fs";
107
+ import { join as join3 } from "path";
108
108
  import { randomUUID } from "crypto";
109
109
 
110
110
  // src/lib/retired-storage-mode.ts
@@ -129,11 +129,111 @@ function assertNoLegacyStorageMode(env = process.env) {
129
129
  }
130
130
 
131
131
  // src/lib/raw-store-root.ts
132
+ import { resolve as resolve2 } from "path";
133
+
134
+ // src/lib/app-home.ts
135
+ import { existsSync } from "fs";
136
+ import { homedir as homedir2 } from "os";
137
+ import { join as join2, resolve } from "path";
138
+
139
+ // ../../node_modules/.bun/@hasna+paths@0.1.0/node_modules/@hasna/paths/dist/index.js
132
140
  import { homedir } from "os";
133
- import { join, resolve } from "path";
141
+ import { join } from "path";
142
+ var KIND_ENV = {
143
+ config: "HASNA_CONFIG_HOME",
144
+ data: "HASNA_DATA_HOME",
145
+ state: "HASNA_STATE_HOME",
146
+ cache: "HASNA_CACHE_HOME"
147
+ };
148
+ var APP_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
149
+ function assertApp(app) {
150
+ if (typeof app !== "string" || app.length === 0) {
151
+ throw new TypeError("paths: app must be a non-empty string");
152
+ }
153
+ if (!APP_SLUG_RE.test(app)) {
154
+ throw new TypeError(`paths: invalid app slug "${app}" \u2014 expected lowercase kebab-case ([a-z0-9]+(-[a-z0-9]+)*)`);
155
+ }
156
+ }
157
+ function envOf(options) {
158
+ return options.env ?? process.env;
159
+ }
160
+ function envValue(options, kind) {
161
+ const value = envOf(options)[KIND_ENV[kind]];
162
+ return typeof value === "string" && value.length > 0 ? value : undefined;
163
+ }
164
+ function isMacOS(platform) {
165
+ return platform === "darwin";
166
+ }
167
+ function baseDir(kind, options) {
168
+ const override = envValue(options, kind);
169
+ if (override)
170
+ return override;
171
+ const home = options.home ?? homedir();
172
+ const platform = options.platform ?? process.platform;
173
+ if (isMacOS(platform)) {
174
+ switch (kind) {
175
+ case "config":
176
+ case "data":
177
+ return join(home, "Library", "Application Support", "Hasna");
178
+ case "cache":
179
+ return join(home, "Library", "Caches", "Hasna");
180
+ case "state":
181
+ return join(home, "Library", "Logs", "Hasna");
182
+ }
183
+ }
184
+ switch (kind) {
185
+ case "config":
186
+ return join(home, ".config", "hasna");
187
+ case "data":
188
+ return join(home, ".local", "share", "hasna");
189
+ case "state":
190
+ return join(home, ".local", "state", "hasna");
191
+ case "cache":
192
+ return join(home, ".cache", "hasna");
193
+ }
194
+ }
195
+ function resolvePath(kind, options) {
196
+ assertApp(options.app);
197
+ const appSegment = options.internal === true ? join("internal", options.app) : options.app;
198
+ return join(baseDir(kind, options), appSegment);
199
+ }
200
+ function configDir(options) {
201
+ return resolvePath("config", options);
202
+ }
203
+
204
+ // src/lib/app-home.ts
205
+ var HASNA_CONFIGS_HOME_ENV = "HASNA_CONFIGS_HOME";
206
+ function homeDir(env = process.env) {
207
+ return env["HOME"] || env["USERPROFILE"] || homedir2();
208
+ }
209
+ function legacyStoreHome(env = process.env) {
210
+ return resolve(join2(homeDir(env), ".hasna", "instructions"));
211
+ }
212
+ function resolverStoreHome(env = process.env) {
213
+ return configDir({ app: "configs", env, home: env.HOME || env.USERPROFILE || homedir2() });
214
+ }
215
+ function adoptResolverStoreHome(resolved, env = process.env) {
216
+ const override = env.HASNA_CONFIG_HOME;
217
+ if (typeof override === "string" && override.trim().length > 0)
218
+ return true;
219
+ return existsSync(join2(resolved, "instructions.db"));
220
+ }
221
+ function exactStoreHome(env = process.env) {
222
+ const v = env[HASNA_CONFIGS_HOME_ENV];
223
+ return v && v.trim() ? v.trim() : undefined;
224
+ }
225
+ function getConfigsStoreHome(env = process.env) {
226
+ const exact = exactStoreHome(env);
227
+ if (exact)
228
+ return resolve(exact);
229
+ const resolved = resolverStoreHome(env);
230
+ return adoptResolverStoreHome(resolved, env) ? resolve(resolved) : legacyStoreHome(env);
231
+ }
232
+
233
+ // src/lib/raw-store-root.ts
134
234
  var RAW_STORE_ROOT_ENV = "HASNA_CONFIGS_HOME";
135
- function getRawStoreRoot() {
136
- return resolve(process.env[RAW_STORE_ROOT_ENV] || join(process.env["HOME"] || homedir(), ".hasna", "instructions"));
235
+ function getRawStoreRoot(env = process.env) {
236
+ return resolve2(getConfigsStoreHome(env));
137
237
  }
138
238
 
139
239
  // src/db/database.ts
@@ -143,7 +243,7 @@ function getDbPath() {
143
243
  }
144
244
  const dir = getRawStoreRoot();
145
245
  mkdirSync(dir, { recursive: true });
146
- return join2(dir, "instructions.db");
246
+ return join3(dir, "instructions.db");
147
247
  }
148
248
  function uuid() {
149
249
  return randomUUID();
@@ -267,7 +367,7 @@ function resetLocalDatabase() {
267
367
  if (dbPath === ":memory:")
268
368
  return;
269
369
  for (const p of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
270
- if (existsSync(p))
370
+ if (existsSync2(p))
271
371
  rmSync(p);
272
372
  }
273
373
  }
@@ -539,9 +639,9 @@ function getConfigStats(db) {
539
639
  }
540
640
 
541
641
  // src/lib/machine.ts
542
- import { arch as currentArch, homedir as homedir2, hostname as currentHostname, type as currentOsType } from "os";
543
- import { existsSync as existsSync2 } from "fs";
544
- import { join as join3 } from "path";
642
+ import { arch as currentArch, homedir as homedir3, hostname as currentHostname, type as currentOsType } from "os";
643
+ import { existsSync as existsSync3 } from "fs";
644
+ import { join as join4 } from "path";
545
645
 
546
646
  // src/lib/template.ts
547
647
  var VAR_PATTERN = /\{\{([A-Z0-9_]+)(?::([^}]*))?\}\}/g;
@@ -614,11 +714,11 @@ function normalizeOsFamily(os) {
614
714
  return value || "unknown";
615
715
  }
616
716
  function detectMachineContext(overrides = {}) {
617
- const homeDir = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir2();
717
+ const homeDir2 = overrides.home_dir ?? process.env["CONFIGS_HOME"] ?? process.env["HOME"] ?? homedir3();
618
718
  const os = overrides.os ?? currentOsType();
619
719
  const osFamily = normalizeOsFamily(os);
620
- const bunBinDir = overrides.bun_bin_dir ?? join3(homeDir, ".bun", "bin");
621
- const defaultBunPath = osFamily === "macos" && existsSync2(BREW_BUN_PATH) ? BREW_BUN_PATH : join3(bunBinDir, "bun");
720
+ const bunBinDir = overrides.bun_bin_dir ?? join4(homeDir2, ".bun", "bin");
721
+ const defaultBunPath = osFamily === "macos" && existsSync3(BREW_BUN_PATH) ? BREW_BUN_PATH : join4(bunBinDir, "bun");
622
722
  return {
623
723
  id: "current-machine",
624
724
  hostname: overrides.hostname ?? currentHostname(),
@@ -627,11 +727,11 @@ function detectMachineContext(overrides = {}) {
627
727
  last_applied_at: null,
628
728
  created_at: "",
629
729
  os_family: osFamily,
630
- home_dir: homeDir,
631
- workspace_root: overrides.workspace_root ?? join3(homeDir, osFamily === "macos" ? "Workspace" : "workspace"),
730
+ home_dir: homeDir2,
731
+ workspace_root: overrides.workspace_root ?? join4(homeDir2, osFamily === "macos" ? "Workspace" : "workspace"),
632
732
  bun_bin_dir: bunBinDir,
633
733
  bun_path: overrides.bun_path ?? defaultBunPath,
634
- path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join3("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
734
+ path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join4("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
635
735
  };
636
736
  }
637
737
  function machineContextToVariables(machine) {
@@ -749,9 +849,9 @@ import { createHash as createHash7 } from "crypto";
749
849
 
750
850
  // src/lib/session-render.ts
751
851
  import { createHash as createHash6 } from "crypto";
752
- import { existsSync as existsSync5, readFileSync as readFileSync4, realpathSync as realpathSync2, statSync as statSync3 } from "fs";
753
- import { homedir as homedir5 } from "os";
754
- import { basename as basename4, dirname as dirname3, extname as extname2, isAbsolute as isAbsolute3, join as join7, parse as parse2, posix as posix2, relative as relative2, resolve as resolve6 } from "path";
852
+ import { existsSync as existsSync6, readFileSync as readFileSync4, realpathSync as realpathSync2, statSync as statSync3 } from "fs";
853
+ import { homedir as homedir6 } from "os";
854
+ 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 resolve7 } from "path";
755
855
 
756
856
  // src/lib/global-agent-rules-standard.ts
757
857
  import { createHash } from "crypto";
@@ -1064,7 +1164,7 @@ import { dlopen, FFIType } from "bun:ffi";
1064
1164
  import {
1065
1165
  closeSync,
1066
1166
  constants,
1067
- existsSync as existsSync3,
1167
+ existsSync as existsSync4,
1068
1168
  fstatSync,
1069
1169
  fsyncSync,
1070
1170
  lstatSync,
@@ -1077,7 +1177,7 @@ import {
1077
1177
  statSync,
1078
1178
  writeFileSync
1079
1179
  } from "fs";
1080
- import { basename, dirname, isAbsolute, join as join4, parse, relative, resolve as resolve2 } from "path";
1180
+ import { basename, dirname, isAbsolute, join as join5, parse, relative, resolve as resolve3 } from "path";
1081
1181
 
1082
1182
  // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
1083
1183
  var exports_external = {};
@@ -5573,7 +5673,7 @@ function planProjectContext(input) {
5573
5673
  const inlineMarkerOverhead = nativeImports ? 0 : Buffer.byteLength(buildManagedBlock(bundle, "", `
5574
5674
  `), "utf8");
5575
5675
  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)));
5576
- const previousTargetContent = existsSync3(paths.target) ? readUtf8RegularFile(paths.target, workspaceRoot, managedObservationMaxBytes(relativePosix(workspaceRoot, paths.target))) : null;
5676
+ const previousTargetContent = existsSync4(paths.target) ? readUtf8RegularFile(paths.target, workspaceRoot, managedObservationMaxBytes(relativePosix(workspaceRoot, paths.target))) : null;
5577
5677
  const markerParse = parseManagedBlock(previousTargetContent ?? "", input.force === true);
5578
5678
  if (markerParse.block && markerParse.block.id !== bundle.project.id) {
5579
5679
  throw new ProjectContextError("MANAGED_BLOCK_CONFLICT", "managed block belongs to a different project");
@@ -5624,7 +5724,7 @@ function composeProjectContextSessionRender(input) {
5624
5724
  return null;
5625
5725
  const { runtime, workspace_root: workspaceRoot, observed_hashes: observedHashes } = guard;
5626
5726
  const paths = runtimePaths(workspaceRoot, runtime);
5627
- if (!existsSync3(paths.manifest))
5727
+ if (!existsSync4(paths.manifest))
5628
5728
  return null;
5629
5729
  assertCodewithTargetIsConsumed(workspaceRoot, runtime);
5630
5730
  const manifest = readProjectContextManifest(paths.manifest, workspaceRoot);
@@ -5653,7 +5753,7 @@ function composeProjectContextSessionRender(input) {
5653
5753
  }
5654
5754
  const fragment = readUtf8RegularFile(paths.fragment, workspaceRoot, PROJECT_CONTEXT_MAX_RENDERED_BYTES);
5655
5755
  scanGeneratedContent(fragment);
5656
- if (!existsSync3(paths.target)) {
5756
+ if (!existsSync4(paths.target)) {
5657
5757
  throw new ProjectContextError("MANAGED_BLOCK_CONFLICT", "project-context provider target is missing while durable context is active");
5658
5758
  }
5659
5759
  const currentTarget = readUtf8RegularFile(paths.target, workspaceRoot, managedObservationMaxBytes(relativePosix(workspaceRoot, paths.target)));
@@ -5664,7 +5764,7 @@ function composeProjectContextSessionRender(input) {
5664
5764
  if (currentMarkers.block.id !== cache.project_id || currentMarkers.block.revision !== cache.revision || currentMarkers.block.hash !== cache.hash) {
5665
5765
  throw new ProjectContextError("MANAGED_BLOCK_CONFLICT", "project-context provider markers differ from the durable cache");
5666
5766
  }
5667
- const plannedIndexes = input.files.filter((file) => file.role === "index" && resolve2(file.path) === paths.target);
5767
+ const plannedIndexes = input.files.filter((file) => file.role === "index" && resolve3(file.path) === paths.target);
5668
5768
  if (plannedIndexes.length !== 1) {
5669
5769
  throw new ProjectContextError("PROJECT_CONTEXT_MANIFEST_INVALID", "session renderer does not own the selected project-context provider target");
5670
5770
  }
@@ -5722,7 +5822,7 @@ function withProjectContextSessionGuard(guard, action, options = {}) {
5722
5822
  verify();
5723
5823
  return action(null);
5724
5824
  }
5725
- const lockPath = resolve2(validated.workspace_root, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
5825
+ const lockPath = resolve3(validated.workspace_root, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
5726
5826
  const lock = acquireWorkspaceLock(validated.workspace_root, lockPath);
5727
5827
  try {
5728
5828
  verify();
@@ -5748,7 +5848,7 @@ function validateProjectContextSessionGuard(guard) {
5748
5848
  if (!isRecord(observed) || typeof observed.path !== "string") {
5749
5849
  throw new ProjectContextError("PROJECT_CONTEXT_SESSION_STALE", "session project-context guard contains malformed hash metadata");
5750
5850
  }
5751
- const path = resolve2(observed.path);
5851
+ const path = resolve3(observed.path);
5752
5852
  if (!allowedPaths.has(path) || observedPaths.has(path)) {
5753
5853
  throw new ProjectContextError("PROJECT_CONTEXT_SESSION_STALE", "session project-context guard contains an unexpected or duplicate path");
5754
5854
  }
@@ -5770,7 +5870,7 @@ function validateProjectContextSessionGuard(guard) {
5770
5870
  function applyProjectContext(options) {
5771
5871
  const workspaceRoot = assertSafeWorkspaceRoot(options.workspace_root);
5772
5872
  const now2 = options.now ?? new Date;
5773
- const lockPath = resolve2(workspaceRoot, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
5873
+ const lockPath = resolve3(workspaceRoot, ...PROJECT_CONTEXT_LOCK_PATH.split("/"));
5774
5874
  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);
5775
5875
  try {
5776
5876
  const resolved = resolveBundleForApply(options, workspaceRoot, now2);
@@ -5917,7 +6017,7 @@ function resolveBundleForApply(options, workspaceRoot, now2) {
5917
6017
  if (!options.expected_project_id) {
5918
6018
  throw new ProjectContextError("PROJECT_CONTEXT_CACHE_ID_REQUIRED", "expected_project_id is required for stale-cache fallback");
5919
6019
  }
5920
- const cachePath = resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
6020
+ const cachePath = resolve3(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
5921
6021
  const cache = readProjectContextCache(cachePath, workspaceRoot);
5922
6022
  if (!cache)
5923
6023
  throw new ProjectContextError("PROJECT_CONTEXT_CACHE_MISSING", "no last-known-good project context cache exists");
@@ -6119,7 +6219,7 @@ function findLegacyCodewithWorkspaceSection(workspaceRoot, runtime, content, bun
6119
6219
  if (runtime !== "codewith" || !content)
6120
6220
  return null;
6121
6221
  const sessionManifestPath = runtimePaths(workspaceRoot, runtime).sessionManifest;
6122
- if (!existsSync3(sessionManifestPath))
6222
+ if (!existsSync4(sessionManifestPath))
6123
6223
  return null;
6124
6224
  const manifest = readSessionManifestRecord(sessionManifestPath, workspaceRoot);
6125
6225
  if (!manifest || manifest["schema"] !== SESSION_RENDER_SCHEMA) {
@@ -6170,7 +6270,7 @@ function assertRevisionOrdering(plan, force) {
6170
6270
  const manifest = readProjectContextManifest(plan.manifest_path, plan.workspace_root);
6171
6271
  if (manifest) {
6172
6272
  const manifestHashHasRecoveryProof = manifest.projectContext.hash === plan.bundle.hash || metadataSnapshotMatchesManifest(plan, manifest);
6173
- 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 && existsSync3(plan.fragment_path) && fragmentMatchesBundle(plan.fragment_path, plan.bundle, plan.workspace_root) && manifestHashHasRecoveryProof;
6273
+ 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;
6174
6274
  observations.push({
6175
6275
  source: "manifest",
6176
6276
  id: manifest.projectContext.projectId,
@@ -6178,7 +6278,7 @@ function assertRevisionOrdering(plan, force) {
6178
6278
  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)
6179
6279
  });
6180
6280
  const fragmentEntry = manifest.files.find((file) => file.relativePath === PROJECT_CONTEXT_FRAGMENT_PATH);
6181
- if (fragmentEntry && existsSync3(plan.fragment_path)) {
6281
+ if (fragmentEntry && existsSync4(plan.fragment_path)) {
6182
6282
  const actual = currentFileHash(plan.fragment_path, plan.workspace_root);
6183
6283
  if (actual !== fragmentEntry.sha256 && !fragmentMatchesBundle(plan.fragment_path, plan.bundle, plan.workspace_root) && !force) {
6184
6284
  throw new ProjectContextError("MANAGED_BLOCK_CONFLICT", "canonical project-context fragment changed outside Instructions");
@@ -6273,9 +6373,9 @@ function buildManifest(plan, now2) {
6273
6373
  function buildSessionCompatibilityManifest(plan, now2) {
6274
6374
  const paths = runtimePaths(plan.workspace_root, plan.runtime);
6275
6375
  const tool = manifestTool(plan.runtime);
6276
- const targetHome = plan.runtime === "codewith" ? resolve2(plan.workspace_root, ".codewith") : plan.workspace_root;
6376
+ const targetHome = plan.runtime === "codewith" ? resolve3(plan.workspace_root, ".codewith") : plan.workspace_root;
6277
6377
  const targetRelativePath = sessionTargetRelativePath(plan.runtime);
6278
- const existing = existsSync3(paths.sessionManifest) ? readSessionManifestRecord(paths.sessionManifest, plan.workspace_root) : {
6378
+ const existing = existsSync4(paths.sessionManifest) ? readSessionManifestRecord(paths.sessionManifest, plan.workspace_root) : {
6279
6379
  schema: SESSION_RENDER_SCHEMA,
6280
6380
  tool,
6281
6381
  adapterMode: plan.native_imports ? "native-imports" : "flattened-markdown",
@@ -6295,7 +6395,7 @@ function buildSessionCompatibilityManifest(plan, now2) {
6295
6395
  throw new ProjectContextError("PROJECT_CONTEXT_MANIFEST_INVALID", "provider session manifest is malformed or incompatible");
6296
6396
  }
6297
6397
  const existingTargetHome = safeLegacyMetadataString(existing["targetHome"], null);
6298
- if (existingTargetHome !== null && resolve2(existingTargetHome) !== targetHome) {
6398
+ if (existingTargetHome !== null && resolve3(existingTargetHome) !== targetHome) {
6299
6399
  throw new ProjectContextError("PROJECT_CONTEXT_MANIFEST_INVALID", "provider session manifest targets a different workspace");
6300
6400
  }
6301
6401
  const sources = sanitizeLegacySources(existing["sources"]).filter((source) => source["id"] !== "project-context-bundle");
@@ -6581,9 +6681,9 @@ function writeMetadataSnapshot(plan, now2) {
6581
6681
  const previous = readProjectContextManifest(plan.manifest_path, plan.workspace_root);
6582
6682
  if (!previous || previous.projectContext.revision === plan.bundle.revision && previous.projectContext.hash === plan.bundle.hash)
6583
6683
  return null;
6584
- const snapshotDir = resolve2(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
6684
+ const snapshotDir = resolve3(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
6585
6685
  ensureSafeDirectory(snapshotDir, plan.workspace_root, 448);
6586
- const snapshotPath = resolve2(snapshotDir, `${safeFilename(previous.projectContext.revision)}-${previous.projectContext.hash.slice(-12)}.json`);
6686
+ const snapshotPath = resolve3(snapshotDir, `${safeFilename(previous.projectContext.revision)}-${previous.projectContext.hash.slice(-12)}.json`);
6587
6687
  const snapshot = {
6588
6688
  schema: "hasna.configs.session-render-snapshot/v1",
6589
6689
  kind: "project-context-metadata",
@@ -6599,9 +6699,9 @@ function writeMetadataSnapshot(plan, now2) {
6599
6699
  return snapshotPath;
6600
6700
  }
6601
6701
  function metadataSnapshotMatchesManifest(plan, manifest) {
6602
- const snapshotDir = resolve2(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
6603
- const snapshotPath = resolve2(snapshotDir, `${safeFilename(manifest.projectContext.revision)}-${manifest.projectContext.hash.slice(-12)}.json`);
6604
- if (!existsSync3(snapshotPath))
6702
+ const snapshotDir = resolve3(plan.workspace_root, ...PROJECT_CONTEXT_SNAPSHOT_DIR.split("/"));
6703
+ const snapshotPath = resolve3(snapshotDir, `${safeFilename(manifest.projectContext.revision)}-${manifest.projectContext.hash.slice(-12)}.json`);
6704
+ if (!existsSync4(snapshotPath))
6605
6705
  return false;
6606
6706
  const record = readJsonRecord(snapshotPath, plan.workspace_root);
6607
6707
  const result = projectContextMetadataSnapshotSchema.safeParse(record);
@@ -6649,10 +6749,10 @@ function writeProjectContextRollbackSnapshot(plan, now2, outputs) {
6649
6749
  sha256: nextHash
6650
6750
  };
6651
6751
  });
6652
- const snapshotDir = resolve2(plan.workspace_root, ...SESSION_RENDER_SNAPSHOT_RELATIVE_DIR.split("/"));
6752
+ const snapshotDir = resolve3(plan.workspace_root, ...SESSION_RENDER_SNAPSHOT_RELATIVE_DIR.split("/"));
6653
6753
  ensureSafeDirectory(snapshotDir, plan.workspace_root, 448);
6654
6754
  const timestamp = now2.toISOString().replace(/[:.]/g, "-");
6655
- const snapshotPath = resolve2(snapshotDir, `${timestamp}-${randomUUID2()}.json`);
6755
+ const snapshotPath = resolve3(snapshotDir, `${timestamp}-${randomUUID2()}.json`);
6656
6756
  const snapshot = {
6657
6757
  schema: "hasna.configs.session-render-snapshot/v2",
6658
6758
  createdAt: now2.toISOString(),
@@ -6670,7 +6770,7 @@ function writeProjectContextRollbackSnapshot(plan, now2, outputs) {
6670
6770
  return snapshotPath;
6671
6771
  }
6672
6772
  function readProjectContextManifest(path, workspaceRoot) {
6673
- if (!existsSync3(path))
6773
+ if (!existsSync4(path))
6674
6774
  return null;
6675
6775
  const record = readJsonRecord(path, workspaceRoot);
6676
6776
  const result = storedManifestObservationSchema.safeParse(record);
@@ -6685,7 +6785,7 @@ function readProjectContextManifest(path, workspaceRoot) {
6685
6785
  };
6686
6786
  }
6687
6787
  function readProjectContextCache(path, workspaceRoot) {
6688
- if (!existsSync3(path))
6788
+ if (!existsSync4(path))
6689
6789
  return null;
6690
6790
  const record = readJsonRecord(path, workspaceRoot);
6691
6791
  const result = projectContextCacheSchema.safeParse(record);
@@ -6717,7 +6817,7 @@ function readSessionManifestRecord(path, workspaceRoot) {
6717
6817
  }
6718
6818
  }
6719
6819
  function atomicWriteFile(path, content, workspaceRoot, defaultMode, expectedHash, afterExchange, atomicExchangeUnavailable = false, beforeInstall, portableCreateOnly = false, maxObservedBytes, allowPortableReplacement = false) {
6720
- const dir = resolve2(path, "..");
6820
+ const dir = resolve3(path, "..");
6721
6821
  ensureSafeDirectory(dir, workspaceRoot, 448);
6722
6822
  assertNoSymlinkSegments(workspaceRoot, path);
6723
6823
  const anchoredOps = portableCreateOnly ? null : resolveAnchoredFsOps();
@@ -6734,7 +6834,7 @@ function atomicWriteFile(path, content, workspaceRoot, defaultMode, expectedHash
6734
6834
  const previous = anchoredFileObservation(directory, targetName);
6735
6835
  const previousMode = previous?.mode ?? defaultMode;
6736
6836
  const tempName = `.project-context-${randomUUID2()}.tmp`;
6737
- const tempPath = join4(dir, tempName);
6837
+ const tempPath = join5(dir, tempName);
6738
6838
  let fd = null;
6739
6839
  let preserveTemp = false;
6740
6840
  let directoryChanged = false;
@@ -6865,7 +6965,7 @@ function atomicWritePortable(path, content, workspaceRoot, defaultMode, expected
6865
6965
  }
6866
6966
  const dir = dirname(path);
6867
6967
  const directoryIdentity = captureManagedDirectoryIdentity(dir, workspaceRoot);
6868
- const tempPath = join4(dir, `.project-context-${randomUUID2()}.tmp`);
6968
+ const tempPath = join5(dir, `.project-context-${randomUUID2()}.tmp`);
6869
6969
  let fd = null;
6870
6970
  let tempIdentity = null;
6871
6971
  try {
@@ -6922,7 +7022,7 @@ function atomicWritePortableReplacement(path, content, workspaceRoot, expectedHa
6922
7022
  }
6923
7023
  const dir = dirname(path);
6924
7024
  const directoryIdentity = captureManagedDirectoryIdentity(dir, workspaceRoot);
6925
- const tempPath = join4(dir, `.project-context-${randomUUID2()}.tmp`);
7025
+ const tempPath = join5(dir, `.project-context-${randomUUID2()}.tmp`);
6926
7026
  const desiredHash = sha2562(content);
6927
7027
  let fd = null;
6928
7028
  let tempIdentity = null;
@@ -6979,7 +7079,7 @@ function portablePreparedHash(tempPath, path, workspaceRoot, maxObservedBytes, s
6979
7079
  function portableFileHash(path, workspaceRoot, maxObservedBytes) {
6980
7080
  if (maxObservedBytes === undefined)
6981
7081
  return currentFileHash(path, workspaceRoot);
6982
- if (!existsSync3(path))
7082
+ if (!existsSync4(path))
6983
7083
  return null;
6984
7084
  assertNoSymlinkSegments(workspaceRoot, path);
6985
7085
  const stat = lstatSync(path);
@@ -6991,11 +7091,11 @@ function portableFileHash(path, workspaceRoot, maxObservedBytes) {
6991
7091
  return createHash2("sha256").update(readFileSync(path)).digest("hex");
6992
7092
  }
6993
7093
  function writeProjectContextCoordinatedFile(input) {
6994
- 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);
7094
+ atomicWriteFile(resolve3(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);
6995
7095
  }
6996
7096
  function removeProjectContextCoordinatedFile(input) {
6997
7097
  const workspaceRoot = assertSafeWorkspaceRoot(input.workspace_root);
6998
- const path = resolve2(input.path);
7098
+ const path = resolve3(input.path);
6999
7099
  assertNoSymlinkSegments(workspaceRoot, path);
7000
7100
  const dir = dirname(path);
7001
7101
  const anchoredOps = input.force_portable_file_ops ? null : resolveAnchoredFsOps();
@@ -7021,7 +7121,7 @@ function removeProjectContextCoordinatedFile(input) {
7021
7121
  throw new ProjectContextHashRace(`managed path changed during deletion: ${relativePosix(workspaceRoot, path)}`);
7022
7122
  }
7023
7123
  displaced = true;
7024
- input.test_hooks?.after_displace?.(join4(dir, displacedName));
7124
+ input.test_hooks?.after_displace?.(join5(dir, displacedName));
7025
7125
  const moved = anchoredFileObservation(directory, displacedName);
7026
7126
  if (!moved || moved.dev !== observed.dev || moved.ino !== observed.ino || moved.hash !== input.expected_hash || anchoredFileObservation(directory, targetName) !== null) {
7027
7127
  throw new ProjectContextHashRace(`managed path changed during deletion validation: ${relativePosix(workspaceRoot, path)}`);
@@ -7067,7 +7167,7 @@ function removePortableCoordinatedFile(path, workspaceRoot, expectedHash, maxObs
7067
7167
  }
7068
7168
  const dir = dirname(path);
7069
7169
  const directoryIdentity = captureManagedDirectoryIdentity(dir, workspaceRoot);
7070
- const displacedPath = join4(dir, `.project-context-delete-${randomUUID2()}.tmp`);
7170
+ const displacedPath = join5(dir, `.project-context-delete-${randomUUID2()}.tmp`);
7071
7171
  let displaced = false;
7072
7172
  try {
7073
7173
  assertManagedDirectoryStable(dir, workspaceRoot, directoryIdentity);
@@ -7078,7 +7178,7 @@ function removePortableCoordinatedFile(path, workspaceRoot, expectedHash, maxObs
7078
7178
  displaced = true;
7079
7179
  afterDisplace?.(displacedPath);
7080
7180
  const moved = lstatSync(displacedPath);
7081
- if (moved.isSymbolicLink() || !moved.isFile() || moved.dev !== observed.dev || moved.ino !== observed.ino || portableFileHash(displacedPath, workspaceRoot, maxObservedBytes) !== expectedHash || existsSync3(path)) {
7181
+ if (moved.isSymbolicLink() || !moved.isFile() || moved.dev !== observed.dev || moved.ino !== observed.ino || portableFileHash(displacedPath, workspaceRoot, maxObservedBytes) !== expectedHash || existsSync4(path)) {
7082
7182
  throw new ProjectContextHashRace(`managed path changed during portable deletion: ${relativePosix(workspaceRoot, path)}`);
7083
7183
  }
7084
7184
  rmSync2(displacedPath);
@@ -7139,7 +7239,7 @@ function anchoredOpenExclusive(directory, name, mode) {
7139
7239
  const requestedMode = mode & 4095;
7140
7240
  let fd;
7141
7241
  try {
7142
- fd = openSync(join4(directory.path, name), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, requestedMode);
7242
+ fd = openSync(join5(directory.path, name), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, requestedMode);
7143
7243
  } catch {
7144
7244
  throw new ProjectContextHashRace(`could not create prepared managed file in ${relativePosix(directory.workspaceRoot, directory.path)}`);
7145
7245
  }
@@ -7182,7 +7282,7 @@ function anchoredFileObservation(directory, name) {
7182
7282
  const stat = fstatSync(fd);
7183
7283
  if (!stat.isFile())
7184
7284
  throw new ProjectContextHashRace("managed output is not a regular file");
7185
- const relativePath = relativePosix(directory.workspaceRoot, join4(directory.path, name));
7285
+ const relativePath = relativePosix(directory.workspaceRoot, join5(directory.path, name));
7186
7286
  const maxBytes = directory.maxObservedBytes === undefined ? managedObservationMaxBytes(relativePath) : directory.maxObservedBytes;
7187
7287
  if (maxBytes !== null && stat.size > maxBytes) {
7188
7288
  throw new ProjectContextHashRace(`managed output exceeds the safe read limit: ${relativePath}`);
@@ -7208,7 +7308,7 @@ function anchoredPreparedObservation(directory, name, path, stage) {
7208
7308
  return observed;
7209
7309
  }
7210
7310
  function captureManagedDirectoryIdentity(path, workspaceRoot) {
7211
- assertNoSymlinkSegments(workspaceRoot, join4(path, ".project-context-directory-guard"));
7311
+ assertNoSymlinkSegments(workspaceRoot, join5(path, ".project-context-directory-guard"));
7212
7312
  let stat;
7213
7313
  try {
7214
7314
  stat = lstatSync(path);
@@ -7221,7 +7321,7 @@ function captureManagedDirectoryIdentity(path, workspaceRoot) {
7221
7321
  return { dev: stat.dev, ino: stat.ino };
7222
7322
  }
7223
7323
  function assertManagedDirectoryStable(path, workspaceRoot, expected) {
7224
- assertNoSymlinkSegments(workspaceRoot, join4(path, ".project-context-directory-guard"));
7324
+ assertNoSymlinkSegments(workspaceRoot, join5(path, ".project-context-directory-guard"));
7225
7325
  let current;
7226
7326
  try {
7227
7327
  current = lstatSync(path);
@@ -7356,10 +7456,10 @@ function resolveAnchoredFsOps() {
7356
7456
  return null;
7357
7457
  }
7358
7458
  function acquireWorkspaceLock(workspaceRoot, lockPath, afterOpen, beforeStaleRemove, processStartIdentityLookup = processStartIdentity) {
7359
- const lockDirectory = resolve2(lockPath, "..");
7459
+ const lockDirectory = resolve3(lockPath, "..");
7360
7460
  ensureSafeDirectory(lockDirectory, workspaceRoot, 448);
7361
7461
  assertNoSymlinkSegments(workspaceRoot, lockPath);
7362
- const tempPath = join4(lockDirectory, `.project-context-lock-${randomUUID2()}.tmp`);
7462
+ const tempPath = join5(lockDirectory, `.project-context-lock-${randomUUID2()}.tmp`);
7363
7463
  let fd = null;
7364
7464
  let openedIdentity = null;
7365
7465
  let openedContentHash = null;
@@ -7393,7 +7493,7 @@ function acquireWorkspaceLock(workspaceRoot, lockPath, afterOpen, beforeStaleRem
7393
7493
  linked = true;
7394
7494
  }
7395
7495
  fsyncDirectory(lockDirectory);
7396
- if (existsSync3(tempPath)) {
7496
+ if (existsSync4(tempPath)) {
7397
7497
  rmSync2(tempPath);
7398
7498
  fsyncDirectory(lockDirectory);
7399
7499
  }
@@ -7408,7 +7508,7 @@ function acquireWorkspaceLock(workspaceRoot, lockPath, afterOpen, beforeStaleRem
7408
7508
  if (linked && openedIdentity && openedContentHash) {
7409
7509
  removeOwnedLockByInode(lockPath, openedIdentity, openedContentHash);
7410
7510
  }
7411
- if (!preserveTemp && existsSync3(tempPath)) {
7511
+ if (!preserveTemp && existsSync4(tempPath)) {
7412
7512
  try {
7413
7513
  rmSync2(tempPath);
7414
7514
  } catch {}
@@ -7423,7 +7523,7 @@ function acquireWorkspaceLock(workspaceRoot, lockPath, afterOpen, beforeStaleRem
7423
7523
  }
7424
7524
  function removeOwnedLockByInode(lockPath, identity, expectedHash) {
7425
7525
  try {
7426
- if (!existsSync3(lockPath))
7526
+ if (!existsSync4(lockPath))
7427
7527
  return;
7428
7528
  const current = lstatSync(lockPath);
7429
7529
  if (current.isSymbolicLink() || current.dev !== identity.dev || current.ino !== identity.ino)
@@ -7431,7 +7531,7 @@ function removeOwnedLockByInode(lockPath, identity, expectedHash) {
7431
7531
  if (expectedHash !== undefined && sha2562(readFileSync(lockPath, "utf8")) !== expectedHash)
7432
7532
  return;
7433
7533
  rmSync2(lockPath);
7434
- fsyncDirectory(resolve2(lockPath, ".."));
7534
+ fsyncDirectory(resolve3(lockPath, ".."));
7435
7535
  } catch {}
7436
7536
  }
7437
7537
  function observeStaleWorkspaceLock(lockPath, workspaceRoot, processStartIdentityLookup = processStartIdentity) {
@@ -7502,7 +7602,7 @@ function tryTakeoverStaleWorkspaceLock(candidatePath, lockPath, workspaceRoot, c
7502
7602
  const candidateInstalled = !current.isSymbolicLink() && current.dev === candidateIdentity.dev && current.ino === candidateIdentity.ino && currentFileHash(lockPath, workspaceRoot) === candidateHash;
7503
7603
  const staleDisplaced = !displaced.isSymbolicLink() && displaced.dev === stale.identity.dev && displaced.ino === stale.identity.ino && currentFileHash(candidatePath, workspaceRoot) === stale.contentHash;
7504
7604
  if (!candidateInstalled || !staleDisplaced) {
7505
- if (candidateInstalled && existsSync3(candidatePath)) {
7605
+ if (candidateInstalled && existsSync4(candidatePath)) {
7506
7606
  atomicExchangePaths(candidatePath, lockPath);
7507
7607
  exchanged = false;
7508
7608
  return false;
@@ -7510,13 +7610,13 @@ function tryTakeoverStaleWorkspaceLock(candidatePath, lockPath, workspaceRoot, c
7510
7610
  throw new ProjectContextError("PROJECT_CONTEXT_LOCK_LOST", "workspace lock changed during stale-lock takeover and could not be restored safely");
7511
7611
  }
7512
7612
  rmSync2(candidatePath);
7513
- fsyncDirectory(resolve2(lockPath, ".."));
7613
+ fsyncDirectory(resolve3(lockPath, ".."));
7514
7614
  exchanged = false;
7515
7615
  return true;
7516
7616
  } catch (error) {
7517
7617
  if (exchanged) {
7518
7618
  try {
7519
- if (currentFileHash(lockPath, workspaceRoot) === candidateHash && existsSync3(candidatePath)) {
7619
+ if (currentFileHash(lockPath, workspaceRoot) === candidateHash && existsSync4(candidatePath)) {
7520
7620
  atomicExchangePaths(candidatePath, lockPath);
7521
7621
  exchanged = false;
7522
7622
  }
@@ -7529,7 +7629,7 @@ function tryTakeoverStaleWorkspaceLock(candidatePath, lockPath, workspaceRoot, c
7529
7629
  }
7530
7630
  }
7531
7631
  function assertWorkspaceLockHeld(lockPath, lock, workspaceRoot) {
7532
- if (!existsSync3(lockPath)) {
7632
+ if (!existsSync4(lockPath)) {
7533
7633
  throw new ProjectContextError("PROJECT_CONTEXT_LOCK_LOST", "workspace project-context lock changed during render");
7534
7634
  }
7535
7635
  const current = lstatSync(lockPath);
@@ -7589,8 +7689,8 @@ function releaseWorkspaceLock(lockPath, lock, workspaceRoot) {
7589
7689
  }
7590
7690
  return;
7591
7691
  }
7592
- const lockDirectory = resolve2(lockPath, "..");
7593
- const releasePath = join4(lockDirectory, `.project-context-release-${randomUUID2()}.tmp`);
7692
+ const lockDirectory = resolve3(lockPath, "..");
7693
+ const releasePath = join5(lockDirectory, `.project-context-release-${randomUUID2()}.tmp`);
7594
7694
  let releaseFd = null;
7595
7695
  let releaseIdentity = null;
7596
7696
  let releaseHash = null;
@@ -7619,7 +7719,7 @@ function releaseWorkspaceLock(lockPath, lock, workspaceRoot) {
7619
7719
  const releaseInstalled = !installed.isSymbolicLink() && installed.dev === releaseIdentity.dev && installed.ino === releaseIdentity.ino && currentFileHash(lockPath, workspaceRoot) === releaseHash;
7620
7720
  const ownedDisplaced = !displaced.isSymbolicLink() && displaced.dev === lock.identity.dev && displaced.ino === lock.identity.ino && currentFileHash(releasePath, workspaceRoot) === lock.contentHash;
7621
7721
  if (!releaseInstalled || !ownedDisplaced) {
7622
- if (releaseInstalled && existsSync3(releasePath)) {
7722
+ if (releaseInstalled && existsSync4(releasePath)) {
7623
7723
  atomicExchangePaths(releasePath, lockPath);
7624
7724
  exchanged = false;
7625
7725
  }
@@ -7632,7 +7732,7 @@ function releaseWorkspaceLock(lockPath, lock, workspaceRoot) {
7632
7732
  } catch {
7633
7733
  if (exchanged) {
7634
7734
  try {
7635
- if (releaseHash && currentFileHash(lockPath, workspaceRoot) === releaseHash && existsSync3(releasePath)) {
7735
+ if (releaseHash && currentFileHash(lockPath, workspaceRoot) === releaseHash && existsSync4(releasePath)) {
7636
7736
  atomicExchangePaths(releasePath, lockPath);
7637
7737
  exchanged = false;
7638
7738
  }
@@ -7644,7 +7744,7 @@ function releaseWorkspaceLock(lockPath, lock, workspaceRoot) {
7644
7744
  closeSync(releaseFd);
7645
7745
  } catch {}
7646
7746
  }
7647
- if (!exchanged && existsSync3(releasePath)) {
7747
+ if (!exchanged && existsSync4(releasePath)) {
7648
7748
  try {
7649
7749
  rmSync2(releasePath);
7650
7750
  } catch {}
@@ -7670,15 +7770,15 @@ function ensureSafeDirectory(path, workspaceRoot, mode) {
7670
7770
  const segments = rel.split(/[\\/]+/).filter(Boolean);
7671
7771
  let current = workspaceRoot;
7672
7772
  for (const segment of segments) {
7673
- current = join4(current, segment);
7674
- if (existsSync3(current)) {
7773
+ current = join5(current, segment);
7774
+ if (existsSync4(current)) {
7675
7775
  if (lstatSync(current).isSymbolicLink())
7676
7776
  throw new ProjectContextError("PROJECT_CONTEXT_SYMLINK_REJECTED", `managed path uses a symlink: ${current}`);
7677
7777
  if (!statSync(current).isDirectory())
7678
7778
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", `managed path is not a directory: ${current}`);
7679
7779
  } else {
7680
7780
  mkdirSync2(current, { mode });
7681
- fsyncDirectory(resolve2(current, ".."));
7781
+ fsyncDirectory(resolve3(current, ".."));
7682
7782
  }
7683
7783
  }
7684
7784
  }
@@ -7734,11 +7834,11 @@ function scanGeneratedContent(content) {
7734
7834
  function runtimePaths(workspaceRoot, runtime) {
7735
7835
  const relativeTarget = runtime === "claude" ? "CLAUDE.md" : runtime === "codewith" ? ".codewith/CODEWITH.md" : "AGENTS.md";
7736
7836
  return {
7737
- target: resolve2(workspaceRoot, ...relativeTarget.split("/")),
7738
- fragment: resolve2(workspaceRoot, ...PROJECT_CONTEXT_FRAGMENT_PATH.split("/")),
7739
- manifest: resolve2(workspaceRoot, ...PROJECT_CONTEXT_MANIFEST_PATH.split("/")),
7740
- cache: resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/")),
7741
- sessionManifest: runtime === "codewith" ? resolve2(workspaceRoot, ".codewith", ".hasna", "session-render-manifest.json") : resolve2(workspaceRoot, ".hasna", "session-render-manifest.json")
7837
+ target: resolve3(workspaceRoot, ...relativeTarget.split("/")),
7838
+ fragment: resolve3(workspaceRoot, ...PROJECT_CONTEXT_FRAGMENT_PATH.split("/")),
7839
+ manifest: resolve3(workspaceRoot, ...PROJECT_CONTEXT_MANIFEST_PATH.split("/")),
7840
+ cache: resolve3(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/")),
7841
+ sessionManifest: runtime === "codewith" ? resolve3(workspaceRoot, ".codewith", ".hasna", "session-render-manifest.json") : resolve3(workspaceRoot, ".hasna", "session-render-manifest.json")
7742
7842
  };
7743
7843
  }
7744
7844
  function projectContextSessionGuardPaths(paths, runtime) {
@@ -7748,7 +7848,7 @@ function projectContextSessionGuardPaths(paths, runtime) {
7748
7848
  paths.fragment,
7749
7849
  paths.target,
7750
7850
  paths.sessionManifest,
7751
- ...runtime === "codewith" ? [resolve2(paths.target, "..", "CODEWITH.override.md")] : []
7851
+ ...runtime === "codewith" ? [resolve3(paths.target, "..", "CODEWITH.override.md")] : []
7752
7852
  ];
7753
7853
  }
7754
7854
  function sessionTargetRelativePath(runtime) {
@@ -7768,27 +7868,27 @@ function projectContextRuntimeForSessionTool(tool) {
7768
7868
  return null;
7769
7869
  }
7770
7870
  function projectContextWorkspaceForSession(input, runtime) {
7771
- const targetHome = resolve2(input.target_home);
7871
+ const targetHome = resolve3(input.target_home);
7772
7872
  if (runtime === "codewith") {
7773
7873
  const workspaceRoot = basename(targetHome) === ".codewith" ? dirname(targetHome) : null;
7774
7874
  if (!workspaceRoot)
7775
7875
  return null;
7776
- if (input.project_root && resolve2(input.project_root) !== workspaceRoot) {
7876
+ if (input.project_root && resolve3(input.project_root) !== workspaceRoot) {
7777
7877
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", "Codewith project_root must be the parent workspace of target_home");
7778
7878
  }
7779
- if (!existsSync3(workspaceRoot) || !lstatSync(workspaceRoot).isDirectory())
7879
+ if (!existsSync4(workspaceRoot) || !lstatSync(workspaceRoot).isDirectory())
7780
7880
  return null;
7781
7881
  return assertSafeWorkspaceRoot(workspaceRoot);
7782
7882
  }
7783
- if (!existsSync3(targetHome) || !lstatSync(targetHome).isDirectory())
7883
+ if (!existsSync4(targetHome) || !lstatSync(targetHome).isDirectory())
7784
7884
  return null;
7785
7885
  return assertSafeWorkspaceRoot(targetHome);
7786
7886
  }
7787
7887
  function assertCodewithTargetIsConsumed(workspaceRoot, runtime) {
7788
7888
  if (runtime !== "codewith")
7789
7889
  return;
7790
- const override = resolve2(workspaceRoot, ".codewith", "CODEWITH.override.md");
7791
- if (!existsSync3(override))
7890
+ const override = resolve3(workspaceRoot, ".codewith", "CODEWITH.override.md");
7891
+ if (!existsSync4(override))
7792
7892
  return;
7793
7893
  assertNoSymlinkSegments(workspaceRoot, override);
7794
7894
  if (!lstatSync(override).isFile())
@@ -7798,10 +7898,10 @@ function assertCodewithTargetIsConsumed(workspaceRoot, runtime) {
7798
7898
  function assertSafeWorkspaceRoot(path) {
7799
7899
  if (!isAbsolute(path))
7800
7900
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", "workspace root must be absolute");
7801
- const normalized = resolve2(path);
7901
+ const normalized = resolve3(path);
7802
7902
  if (normalized === parse(normalized).root)
7803
7903
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", "workspace root cannot be the filesystem root");
7804
- if (!existsSync3(normalized) || !lstatSync(normalized).isDirectory())
7904
+ if (!existsSync4(normalized) || !lstatSync(normalized).isDirectory())
7805
7905
  throw new ProjectContextError("PROJECT_CONTEXT_PATH_INVALID", "workspace root must be an existing directory");
7806
7906
  assertNoSymlinkAncestors(normalized);
7807
7907
  if (lstatSync(normalized).isSymbolicLink())
@@ -7815,18 +7915,18 @@ function assertNoSymlinkSegments(root, target) {
7815
7915
  }
7816
7916
  let current = root;
7817
7917
  for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
7818
- current = join4(current, segment);
7819
- if (existsSync3(current) && lstatSync(current).isSymbolicLink()) {
7918
+ current = join5(current, segment);
7919
+ if (existsSync4(current) && lstatSync(current).isSymbolicLink()) {
7820
7920
  throw new ProjectContextError("PROJECT_CONTEXT_SYMLINK_REJECTED", `managed path uses a symlink: ${current}`);
7821
7921
  }
7822
7922
  }
7823
7923
  }
7824
7924
  function assertNoSymlinkAncestors(path) {
7825
- const normalized = resolve2(path);
7925
+ const normalized = resolve3(path);
7826
7926
  let current = parse(normalized).root;
7827
7927
  for (const segment of relative(current, normalized).split(/[\\/]+/).filter(Boolean)) {
7828
- current = join4(current, segment);
7829
- if (!existsSync3(current))
7928
+ current = join5(current, segment);
7929
+ if (!existsSync4(current))
7830
7930
  return;
7831
7931
  if (lstatSync(current).isSymbolicLink())
7832
7932
  throw new ProjectContextError("PROJECT_CONTEXT_SYMLINK_REJECTED", `workspace ancestor is a symlink: ${current}`);
@@ -7842,7 +7942,7 @@ function readUtf8RegularFile(path, workspaceRoot, maxBytes = FOREIGN_INPUT_MAX_B
7842
7942
  return readFileSync(path, "utf8");
7843
7943
  }
7844
7944
  function currentFileHash(path, workspaceRoot) {
7845
- if (!existsSync3(path))
7945
+ if (!existsSync4(path))
7846
7946
  return null;
7847
7947
  const relativePath = relativePosix(workspaceRoot, path);
7848
7948
  return sha2562(readUtf8RegularFile(path, workspaceRoot, managedObservationMaxBytes(relativePath)));
@@ -7861,10 +7961,10 @@ function fragmentMatchesBundle(path, bundle, workspaceRoot) {
7861
7961
  }
7862
7962
  function durableSourcePath(path, workspaceRoot) {
7863
7963
  if (!path || path.startsWith("/dev/fd/"))
7864
- return resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
7865
- const normalized = isAbsolute(path) ? resolve2(path) : resolve2(workspaceRoot, path);
7964
+ return resolve3(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
7965
+ const normalized = isAbsolute(path) ? resolve3(path) : resolve3(workspaceRoot, path);
7866
7966
  if (normalized.startsWith("/dev/fd/"))
7867
- return resolve2(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
7967
+ return resolve3(workspaceRoot, ...PROJECT_CONTEXT_CACHE_PATH.split("/"));
7868
7968
  return normalized;
7869
7969
  }
7870
7970
  function compareRevisions(incoming, previous) {
@@ -8205,7 +8305,7 @@ function compareProviderVersions(left, right) {
8205
8305
 
8206
8306
  // src/lib/asset-plan.ts
8207
8307
  import { createHash as createHash3 } from "crypto";
8208
- import { isAbsolute as isAbsolute2, posix, resolve as resolve3 } from "path";
8308
+ import { isAbsolute as isAbsolute2, posix, resolve as resolve4 } from "path";
8209
8309
  var ASSET_PLAN_SCHEMA = "hasna.instructions.asset-plan/v1";
8210
8310
  var ASSET_CAPABILITY_SCHEMA = "hasna.instructions.asset-capability/v1";
8211
8311
  var ASSET_BUNDLE_SCHEMA = "hasna.instructions.asset-bundle/v1";
@@ -8470,8 +8570,8 @@ function resolveAssetDestination(item, roots) {
8470
8570
  if (!isAbsolute2(root))
8471
8571
  throw new Error(`Asset ${item.assetKey} destination root must be absolute.`);
8472
8572
  const relativePath = safeRelativePath(item.destination.relativePath);
8473
- const target = resolve3(root, ...relativePath.split("/"));
8474
- const normalizedRoot = resolve3(root);
8573
+ const target = resolve4(root, ...relativePath.split("/"));
8574
+ const normalizedRoot = resolve4(root);
8475
8575
  if (target === normalizedRoot)
8476
8576
  throw new Error(`Asset ${item.assetKey} destination cannot replace its root.`);
8477
8577
  if (!target.startsWith(`${normalizedRoot}/`))
@@ -8593,8 +8693,8 @@ function deepFreeze(value) {
8593
8693
  // src/lib/cursor-authority.ts
8594
8694
  import { createHash as createHash4 } from "crypto";
8595
8695
  import { lstatSync as lstatSync2, readFileSync as readFileSync2 } from "fs";
8596
- import { homedir as homedir3 } from "os";
8597
- import { join as join5, resolve as resolve4 } from "path";
8696
+ import { homedir as homedir4 } from "os";
8697
+ import { join as join6, resolve as resolve5 } from "path";
8598
8698
  var CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH = ".cursor/rules/hasna-global.mdc";
8599
8699
  var CURSOR_GLOBAL_AUTHORITY_MAX_BYTES = 256 * 1024;
8600
8700
  var CURSOR_GLOBAL_AUTHORITY_MANAGED_MARKER = "Managed by @hasna/configs cursor global authority";
@@ -8603,8 +8703,8 @@ var CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN = /^---\n[\s\S]*?\n---(?:\n|$)/;
8603
8703
  function sha2564(content) {
8604
8704
  return createHash4("sha256").update(content).digest("hex");
8605
8705
  }
8606
- function homeDir() {
8607
- return process.env["HOME"] || homedir3();
8706
+ function homeDir2() {
8707
+ return process.env["HOME"] || homedir4();
8608
8708
  }
8609
8709
  function markerPayload(content, markerLine, markerIndex) {
8610
8710
  const index = markerIndex ?? content.indexOf(markerLine);
@@ -8620,12 +8720,12 @@ function baseObservation(path) {
8620
8720
  };
8621
8721
  }
8622
8722
  function observeCursorGlobalAuthority(options = {}) {
8623
- const authorityPath = resolve4(join5(options.home ?? homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
8723
+ const authorityPath = resolve5(join6(options.home ?? homeDir2(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
8624
8724
  const readFile = options.readFile ?? ((path) => readFileSync2(path, "utf8"));
8625
8725
  return observeCursorGlobalAuthorityPath(authorityPath, readFile);
8626
8726
  }
8627
8727
  function observeCursorGlobalAuthorityAtPath(authorityPath) {
8628
- return observeCursorGlobalAuthorityPath(resolve4(authorityPath), (path) => readFileSync2(path, "utf8"));
8728
+ return observeCursorGlobalAuthorityPath(resolve5(authorityPath), (path) => readFileSync2(path, "utf8"));
8629
8729
  }
8630
8730
  function observeCursorGlobalAuthorityPath(authorityPath, readFile) {
8631
8731
  const base = baseObservation(authorityPath);
@@ -8770,7 +8870,7 @@ function observeCursorGlobalAuthorityPath(authorityPath, readFile) {
8770
8870
  };
8771
8871
  }
8772
8872
  function isCursorGlobalAuthorityPath(path) {
8773
- return resolve4(path) === resolve4(join5(homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
8873
+ return resolve5(path) === resolve5(join6(homeDir2(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
8774
8874
  }
8775
8875
  function stampCursorGlobalAuthorityMarker(content) {
8776
8876
  const existing = content.match(CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN);
@@ -8820,8 +8920,8 @@ function detectCursorAuthorityConflicts(observation = observeCursorGlobalAuthori
8820
8920
  // src/lib/session-authority.ts
8821
8921
  import { createHash as createHash5 } from "crypto";
8822
8922
  import { lstatSync as lstatSync3, readFileSync as readFileSync3, realpathSync, statSync as statSync2 } from "fs";
8823
- import { homedir as homedir4 } from "os";
8824
- import { join as join6, resolve as resolve5 } from "path";
8923
+ import { homedir as homedir5 } from "os";
8924
+ import { join as join7, resolve as resolve6 } from "path";
8825
8925
  var CLAUDE_LEGACY_AUTHORITY_RELATIVE_PATH = "AGENTS.md";
8826
8926
  var CLAUDE_LEGACY_AUTHORITY_MAX_BYTES = 256 * 1024;
8827
8927
  var CLAUDE_LEGACY_MARKERS = [
@@ -8833,10 +8933,10 @@ function sha2565(content) {
8833
8933
  return createHash5("sha256").update(content).digest("hex");
8834
8934
  }
8835
8935
  function configHomeDir() {
8836
- return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir4();
8936
+ return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir5();
8837
8937
  }
8838
8938
  function normalizeOwnedTargetPath(p) {
8839
- const expanded = p.startsWith("~/") ? resolve5(configHomeDir(), p.slice(2)) : resolve5(p);
8939
+ const expanded = p.startsWith("~/") ? resolve6(configHomeDir(), p.slice(2)) : resolve6(p);
8840
8940
  try {
8841
8941
  return realpathSync(expanded);
8842
8942
  } catch {
@@ -8844,7 +8944,7 @@ function normalizeOwnedTargetPath(p) {
8844
8944
  }
8845
8945
  }
8846
8946
  function detectClaudeAuthorityConflicts(targetHome, ownedAuthorities = []) {
8847
- const authorityPath = resolve5(join6(targetHome, CLAUDE_LEGACY_AUTHORITY_RELATIVE_PATH));
8947
+ const authorityPath = resolve6(join7(targetHome, CLAUDE_LEGACY_AUTHORITY_RELATIVE_PATH));
8848
8948
  let stat;
8849
8949
  try {
8850
8950
  stat = lstatSync3(authorityPath);
@@ -9203,13 +9303,13 @@ function yamlQuote2(value) {
9203
9303
  return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
9204
9304
  }
9205
9305
  function defaultTargetHome(tool, profile, sessionId) {
9206
- const home = process.env["HOME"] || homedir5();
9207
- return join7(home, ".hasna", "accounts", "profiles", tool, slug(profile));
9306
+ const home = process.env["HOME"] || homedir6();
9307
+ return join8(home, ".hasna", "accounts", "profiles", tool, slug(profile));
9208
9308
  }
9209
9309
  function joinTarget(targetHome, relativePath) {
9210
9310
  const safeTargetHome = assertSafeTargetRoot(targetHome);
9211
9311
  const safeRelativePath2 = assertSafeRelativePath(relativePath);
9212
- return join7(safeTargetHome, ...safeRelativePath2.split("/"));
9312
+ return join8(safeTargetHome, ...safeRelativePath2.split("/"));
9213
9313
  }
9214
9314
  function makeFile(targetHome, relativePath, role, content, sourceIds) {
9215
9315
  const safeTargetHome = assertSafeTargetRoot(targetHome);
@@ -9779,7 +9879,7 @@ function buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfi
9779
9879
  ...sources.flatMap((source) => source.resolvedRules.map((rule) => rule.id))
9780
9880
  ]);
9781
9881
  const existingConfigPath = joinTarget(targetHome, adapter.configFile);
9782
- const selectedConfig = existsSync5(existingConfigPath) ? readOpenCodeConfig(readFileSync4(existingConfigPath, "utf8"), existingConfigPath) : providerConfig ? readOpenCodeConfig(providerConfig.content, providerConfig.sourceId) : {};
9882
+ const selectedConfig = existsSync6(existingConfigPath) ? readOpenCodeConfig(readFileSync4(existingConfigPath, "utf8"), existingConfigPath) : providerConfig ? readOpenCodeConfig(providerConfig.content, providerConfig.sourceId) : {};
9783
9883
  const preservedInstructions = normalizeOpenCodeInstructions(selectedConfig["instructions"]).filter((path) => !pathIsManagedOpenCodeInstruction(path, adapter.managedDir));
9784
9884
  const config = {
9785
9885
  ...selectedConfig,
@@ -9968,7 +10068,7 @@ function adapterFor(input) {
9968
10068
  return gatedNativeImports ? CODEWITH_NATIVE_ADAPTER : CODEWITH_FLATTENED_ADAPTER;
9969
10069
  }
9970
10070
  function getHomeDir() {
9971
- return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir5();
10071
+ return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir6();
9972
10072
  }
9973
10073
  function cleanSessionPathInput(path) {
9974
10074
  const trimmed = path.trim();
@@ -9983,16 +10083,16 @@ function resolveSessionPath(path) {
9983
10083
  throw new Error("Session render path cannot be empty.");
9984
10084
  const home = getHomeDir();
9985
10085
  if (cleaned === "~")
9986
- return resolve6(home);
10086
+ return resolve7(home);
9987
10087
  if (cleaned.startsWith("~/"))
9988
- return resolve6(home, cleaned.slice(2));
10088
+ return resolve7(home, cleaned.slice(2));
9989
10089
  if (cleaned === "{{HOME}}" || cleaned === "${HOME}")
9990
- return resolve6(home);
10090
+ return resolve7(home);
9991
10091
  if (cleaned.startsWith("{{HOME}}/"))
9992
- return resolve6(home, cleaned.slice("{{HOME}}/".length));
10092
+ return resolve7(home, cleaned.slice("{{HOME}}/".length));
9993
10093
  if (cleaned.startsWith("${HOME}/"))
9994
- return resolve6(home, cleaned.slice("${HOME}/".length));
9995
- return resolve6(cleaned);
10094
+ return resolve7(home, cleaned.slice("${HOME}/".length));
10095
+ return resolve7(cleaned);
9996
10096
  }
9997
10097
  function assertSafeRelativePath(relativePath) {
9998
10098
  if (!relativePath.trim())
@@ -10008,7 +10108,7 @@ function assertSafeRelativePath(relativePath) {
10008
10108
  function assertSafeTargetRoot(targetHome) {
10009
10109
  if (!isAbsolute3(targetHome))
10010
10110
  throw new Error(`Session render target must be an absolute path: ${targetHome}`);
10011
- const normalized = resolve6(targetHome);
10111
+ const normalized = resolve7(targetHome);
10012
10112
  if (normalized === parse2(normalized).root) {
10013
10113
  throw new Error(`Session render target cannot be the filesystem root: ${targetHome}`);
10014
10114
  }
@@ -10244,7 +10344,7 @@ function planSessionRender(input) {
10244
10344
  sourceId: input.providerConfig.sourceId,
10245
10345
  selectedPayloadSha256: sha2566(input.providerConfig.content),
10246
10346
  renderedPayloadSha256: files.find((file) => file.relativePath === adapter.configFile)?.sha256 ?? sha2566(input.providerConfig.content),
10247
- selected: !existsSync5(joinTarget(targetHome, adapter.configFile))
10347
+ selected: !existsSync6(joinTarget(targetHome, adapter.configFile))
10248
10348
  }
10249
10349
  } : {},
10250
10350
  ...projectContext ? {
@@ -10606,10 +10706,10 @@ function layerFromIdentityKind(kind, exportShape) {
10606
10706
  function contentFromIdentitySourcePaths(sourcePaths, exportPath, sourceId) {
10607
10707
  if (sourcePaths.length === 0 || !exportPath)
10608
10708
  return;
10609
- const baseDir = dirname3(resolveSessionPath(exportPath));
10709
+ const baseDir2 = dirname3(resolveSessionPath(exportPath));
10610
10710
  const contents = [];
10611
10711
  for (const sourcePath of sourcePaths) {
10612
- const content = readIdentitySourcePath(sourcePath, baseDir, sourceId);
10712
+ const content = readIdentitySourcePath(sourcePath, baseDir2, sourceId);
10613
10713
  if (content !== undefined)
10614
10714
  contents.push({ path: sourcePath.path, content });
10615
10715
  }
@@ -10622,9 +10722,9 @@ ${item.content.trimEnd()}`).join(`
10622
10722
 
10623
10723
  `));
10624
10724
  }
10625
- function readIdentitySourcePath(sourcePath, baseDir, sourceId) {
10626
- const resolvedPath = resolveIdentitySourcePath(sourcePath.path, baseDir, sourceId);
10627
- if (!existsSync5(resolvedPath)) {
10725
+ function readIdentitySourcePath(sourcePath, baseDir2, sourceId) {
10726
+ const resolvedPath = resolveIdentitySourcePath(sourcePath.path, baseDir2, sourceId);
10727
+ if (!existsSync6(resolvedPath)) {
10628
10728
  if (sourcePath.required) {
10629
10729
  throw new Error(`Required identity instruction source path not found for ${sourceId}: ${sourcePath.path}`);
10630
10730
  }
@@ -10634,27 +10734,27 @@ function readIdentitySourcePath(sourcePath, baseDir, sourceId) {
10634
10734
  if (!stat.isFile()) {
10635
10735
  throw new Error(`Identity instruction source path is not a file for ${sourceId}: ${sourcePath.path}`);
10636
10736
  }
10637
- const realBase = realpathSync2(baseDir);
10737
+ const realBase = realpathSync2(baseDir2);
10638
10738
  const realPath = realpathSync2(resolvedPath);
10639
10739
  if (!pathIsInside(realPath, realBase)) {
10640
10740
  throw new Error(`Identity instruction source path escapes export directory for ${sourceId}: ${sourcePath.path}`);
10641
10741
  }
10642
10742
  return readFileSync4(realPath, "utf-8");
10643
10743
  }
10644
- function resolveIdentitySourcePath(path, baseDir, sourceId) {
10744
+ function resolveIdentitySourcePath(path, baseDir2, sourceId) {
10645
10745
  const cleaned = cleanSessionPathInput(path);
10646
10746
  if (!cleaned)
10647
10747
  throw new Error(`Identity instruction source path cannot be empty for ${sourceId}.`);
10648
10748
  if (cleaned.includes("\\"))
10649
10749
  throw new Error(`Identity instruction source path must use POSIX separators for ${sourceId}: ${path}`);
10650
- const resolvedPath = isAbsolute3(cleaned) ? resolve6(cleaned) : resolve6(baseDir, cleaned);
10651
- if (!pathIsInside(resolvedPath, resolve6(baseDir))) {
10750
+ const resolvedPath = isAbsolute3(cleaned) ? resolve7(cleaned) : resolve7(baseDir2, cleaned);
10751
+ if (!pathIsInside(resolvedPath, resolve7(baseDir2))) {
10652
10752
  throw new Error(`Identity instruction source path escapes export directory for ${sourceId}: ${path}`);
10653
10753
  }
10654
10754
  return resolvedPath;
10655
10755
  }
10656
- function pathIsInside(path, baseDir) {
10657
- const rel = relative2(baseDir, path);
10756
+ function pathIsInside(path, baseDir2) {
10757
+ const rel = relative2(baseDir2, path);
10658
10758
  return rel === "" || !rel.startsWith("..") && !isAbsolute3(rel);
10659
10759
  }
10660
10760
  function providerTargetsTool(targets, tool) {
@@ -12055,16 +12155,16 @@ function resolveConfigStore(env = process.env) {
12055
12155
  return cloud ? new CloudConfigStore(cloud) : new LocalConfigStore;
12056
12156
  }
12057
12157
  // src/status.ts
12058
- import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
12158
+ import { existsSync as existsSync11, readFileSync as readFileSync9 } from "fs";
12059
12159
 
12060
12160
  // src/lib/apply.ts
12061
- import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync6, realpathSync as realpathSync3, writeFileSync as writeFileSync2 } from "fs";
12062
- import { basename as basename5, dirname as dirname5, join as join9, resolve as resolve7 } from "path";
12063
- import { homedir as homedir6 } from "os";
12161
+ import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync6, realpathSync as realpathSync3, writeFileSync as writeFileSync2 } from "fs";
12162
+ import { basename as basename5, dirname as dirname5, join as join10, resolve as resolve8 } from "path";
12163
+ import { homedir as homedir7 } from "os";
12064
12164
 
12065
12165
  // src/lib/session-render-ownership.ts
12066
- import { existsSync as existsSync6, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
12067
- import { dirname as dirname4, join as join8, parse as parse3, relative as relative3, sep } from "path";
12166
+ import { existsSync as existsSync7, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
12167
+ import { dirname as dirname4, join as join9, parse as parse3, relative as relative3, sep } from "path";
12068
12168
  var MANIFEST_ANCESTOR_LIMIT = 24;
12069
12169
  var MANAGED_PATH_SEGMENTS = SESSION_RENDER_EXCLUSIVE_MANAGED_PATHS.map((managedPath) => managedPath.split("/").filter(Boolean));
12070
12170
  var manifestCache = new Map;
@@ -12086,7 +12186,7 @@ function pathIsSessionRenderManagedDir(absolutePath2) {
12086
12186
  function readManifestRelativePaths(manifestPath) {
12087
12187
  let stats;
12088
12188
  try {
12089
- if (!existsSync6(manifestPath))
12189
+ if (!existsSync7(manifestPath))
12090
12190
  return null;
12091
12191
  stats = statSync4(manifestPath);
12092
12192
  } catch {
@@ -12115,7 +12215,7 @@ function sessionRenderManifestClaimsPath(absolutePath2) {
12115
12215
  const root = parse3(absolutePath2).root;
12116
12216
  let home = dirname4(absolutePath2);
12117
12217
  for (let depth = 0;depth < MANIFEST_ANCESTOR_LIMIT; depth += 1) {
12118
- const manifestPath = join8(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
12218
+ const manifestPath = join9(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
12119
12219
  const relativePaths = readManifestRelativePaths(manifestPath);
12120
12220
  if (relativePaths) {
12121
12221
  const claimed = relative3(home, absolutePath2).split(sep).join("/");
@@ -12135,13 +12235,13 @@ function sessionRenderOwnsPath(absolutePath2) {
12135
12235
 
12136
12236
  // src/lib/apply.ts
12137
12237
  function getConfigHome() {
12138
- return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir6();
12238
+ return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir7();
12139
12239
  }
12140
12240
  function expandPath(p) {
12141
12241
  if (p.startsWith("~/")) {
12142
- return resolve7(getConfigHome(), p.slice(2));
12242
+ return resolve8(getConfigHome(), p.slice(2));
12143
12243
  }
12144
- return resolve7(p);
12244
+ return resolve8(p);
12145
12245
  }
12146
12246
  function normalizeTargetPath(p) {
12147
12247
  const expanded = expandPath(p);
@@ -12151,9 +12251,9 @@ function normalizeTargetPath(p) {
12151
12251
  let current = expanded;
12152
12252
  const missingSegments = [];
12153
12253
  while (true) {
12154
- if (existsSync7(current)) {
12254
+ if (existsSync8(current)) {
12155
12255
  try {
12156
- return resolve7(realpathSync3(current), ...missingSegments);
12256
+ return resolve8(realpathSync3(current), ...missingSegments);
12157
12257
  } catch {
12158
12258
  return expanded;
12159
12259
  }
@@ -12182,11 +12282,11 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
12182
12282
  }
12183
12283
  const path = expandPath(renderedTargetPath);
12184
12284
  const renderedForTarget = isCursorGlobalAuthorityPath(path) ? stampCursorGlobalAuthorityMarker(renderedContent) : renderedContent;
12185
- const previousContent = existsSync7(path) ? readFileSync6(path, "utf-8") : null;
12285
+ const previousContent = existsSync8(path) ? readFileSync6(path, "utf-8") : null;
12186
12286
  const changed = previousContent !== renderedForTarget;
12187
12287
  if (!opts.dryRun) {
12188
12288
  const dir = dirname5(path);
12189
- if (!existsSync7(dir)) {
12289
+ if (!existsSync8(dir)) {
12190
12290
  mkdirSync3(dir, { recursive: true });
12191
12291
  }
12192
12292
  if (previousContent !== null && changed) {
@@ -12220,7 +12320,7 @@ function wouldDestroyACredential(targetPath, renderedContent, format) {
12220
12320
  let current;
12221
12321
  try {
12222
12322
  const path = expandPath(targetPath);
12223
- if (!existsSync7(path))
12323
+ if (!existsSync8(path))
12224
12324
  return [];
12225
12325
  current = readFileSync6(path, "utf-8");
12226
12326
  } catch {
@@ -12546,14 +12646,14 @@ function sessionRendererOwnsCanonicalTarget(normalized, opts) {
12546
12646
  getConfigHome(),
12547
12647
  opts.vars?.["HOME_DIR"]
12548
12648
  ].filter((home) => typeof home === "string" && home.length > 0));
12549
- if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join9(home, ...relativePath.split("/"))))))
12649
+ if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join10(home, ...relativePath.split("/"))))))
12550
12650
  return true;
12551
12651
  return sessionRenderOwnsPath(normalized);
12552
12652
  }
12553
12653
 
12554
12654
  // src/lib/package-version.ts
12555
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
12556
- import { dirname as dirname6, join as join10 } from "path";
12655
+ import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
12656
+ import { dirname as dirname6, join as join11 } from "path";
12557
12657
  import { fileURLToPath } from "url";
12558
12658
  var cached = null;
12559
12659
  function getPackageVersion() {
@@ -12562,8 +12662,8 @@ function getPackageVersion() {
12562
12662
  try {
12563
12663
  let dir = dirname6(fileURLToPath(import.meta.url));
12564
12664
  for (let i = 0;i < 8; i++) {
12565
- const pkgPath = join10(dir, "package.json");
12566
- if (existsSync8(pkgPath)) {
12665
+ const pkgPath = join11(dir, "package.json");
12666
+ if (existsSync9(pkgPath)) {
12567
12667
  const pkg = JSON.parse(readFileSync7(pkgPath, "utf8"));
12568
12668
  if (pkg.name === "@hasna/instructions" && pkg.version) {
12569
12669
  cached = pkg.version;
@@ -12584,7 +12684,7 @@ function getPackageVersion() {
12584
12684
  import { createHash as createHash8 } from "crypto";
12585
12685
  import { spawnSync } from "child_process";
12586
12686
  import {
12587
- existsSync as existsSync9,
12687
+ existsSync as existsSync10,
12588
12688
  lstatSync as lstatSync4,
12589
12689
  mkdirSync as mkdirSync4,
12590
12690
  readFileSync as readFileSync8,
@@ -12592,8 +12692,8 @@ import {
12592
12692
  rmSync as rmSync3,
12593
12693
  writeFileSync as writeFileSync3
12594
12694
  } from "fs";
12595
- import { homedir as homedir7 } from "os";
12596
- import { dirname as dirname7, join as join11, parse as parse4, relative as relative4, resolve as resolve8 } from "path";
12695
+ import { homedir as homedir8 } from "os";
12696
+ import { dirname as dirname7, join as join12, parse as parse4, relative as relative4, resolve as resolve9 } from "path";
12597
12697
  var INBOX_CONVERSATIONS_MINIMUM_VERSION = "0.5.28";
12598
12698
  var INBOX_SKILL_MARKERS = [
12599
12699
  [".claude", "skills", "inbox", "SKILL.md"],
@@ -12614,13 +12714,13 @@ function lstatOrNull(path) {
12614
12714
  }
12615
12715
  }
12616
12716
  function findSymlinkedAncestor(path) {
12617
- const normalized = resolve8(path);
12717
+ const normalized = resolve9(path);
12618
12718
  const parsed = parse4(normalized);
12619
12719
  let current = parsed.root;
12620
12720
  const rel = relative4(parsed.root, normalized);
12621
12721
  for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
12622
- current = join11(current, segment);
12623
- if (!existsSync9(current))
12722
+ current = join12(current, segment);
12723
+ if (!existsSync10(current))
12624
12724
  return null;
12625
12725
  if (lstatSync4(current).isSymbolicLink())
12626
12726
  return current;
@@ -12637,11 +12737,11 @@ function packagedInboxSkillPath(explicitPath) {
12637
12737
  if (explicitPath)
12638
12738
  return explicitPath;
12639
12739
  const candidates = [
12640
- join11(import.meta.dir, "..", "..", "assets", "skills", "inbox", "SKILL.md"),
12641
- join11(import.meta.dir, "..", "assets", "skills", "inbox", "SKILL.md"),
12642
- join11(process.cwd(), "assets", "skills", "inbox", "SKILL.md")
12740
+ join12(import.meta.dir, "..", "..", "assets", "skills", "inbox", "SKILL.md"),
12741
+ join12(import.meta.dir, "..", "assets", "skills", "inbox", "SKILL.md"),
12742
+ join12(process.cwd(), "assets", "skills", "inbox", "SKILL.md")
12643
12743
  ];
12644
- const found = candidates.find((candidate) => existsSync9(candidate));
12744
+ const found = candidates.find((candidate) => existsSync10(candidate));
12645
12745
  if (!found) {
12646
12746
  throw new Error(`packaged inbox skill contract is missing (checked ${candidates.length} package-relative locations)`);
12647
12747
  }
@@ -12690,8 +12790,8 @@ function compareVersions(left, right) {
12690
12790
  }
12691
12791
  return 0;
12692
12792
  }
12693
- function inspectSkillMarkers(homeDir2) {
12694
- return INBOX_SKILL_MARKERS.map((parts) => join11(homeDir2, ...parts)).map((path) => {
12793
+ function inspectSkillMarkers(homeDir3) {
12794
+ return INBOX_SKILL_MARKERS.map((parts) => join12(homeDir3, ...parts)).map((path) => {
12695
12795
  const stat = lstatOrNull(path);
12696
12796
  if (!stat)
12697
12797
  return null;
@@ -12707,9 +12807,9 @@ function inspectSkillMarkers(homeDir2) {
12707
12807
  }).filter((snapshot) => snapshot !== null);
12708
12808
  }
12709
12809
  function inspectInbox(options) {
12710
- const homeDir2 = options.homeDir ?? homedir7();
12810
+ const homeDir3 = options.homeDir ?? homedir8();
12711
12811
  const runtimeCommand = options.conversationsCommand ?? "conversations";
12712
- const snapshots = inspectSkillMarkers(homeDir2);
12812
+ const snapshots = inspectSkillMarkers(homeDir3);
12713
12813
  const skillPresent = snapshots.length > 0;
12714
12814
  let canonicalContent = null;
12715
12815
  let canonicalSha256 = null;
@@ -13023,7 +13123,7 @@ async function getConfigsStatus(store = resolveConfigStore(), options = {}) {
13023
13123
  continue;
13024
13124
  knownTargets += 1;
13025
13125
  const targetPath = expandPath(config.target_path);
13026
- if (!existsSync10(targetPath)) {
13126
+ if (!existsSync11(targetPath)) {
13027
13127
  missingTargets += 1;
13028
13128
  continue;
13029
13129
  }
@@ -13119,8 +13219,8 @@ async function getConfigsStatus(store = resolveConfigStore(), options = {}) {
13119
13219
  }
13120
13220
  // src/lib/provider-context.ts
13121
13221
  import { createHash as createHash9 } from "crypto";
13122
- import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync4 } from "fs";
13123
- import { join as join12 } from "path";
13222
+ import { existsSync as existsSync12, mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync4 } from "fs";
13223
+ import { join as join13 } from "path";
13124
13224
  var PROVIDER_CONTEXT_DIR = ".hasna/provider-context";
13125
13225
  var PROVIDER_CONTEXT_MANIFEST = "manifest.json";
13126
13226
  var PROVIDER_CONTEXT_SCHEMA = "hasna.instructions.provider-context/v1";
@@ -13265,17 +13365,17 @@ function resolveAndRenderProviderContext(opts) {
13265
13365
  const recordedEndpoint = originAccepted ? `${opts.origin.host}${opts.origin.pathPrefix || ""}` : null;
13266
13366
  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;
13267
13367
  const content = renderProviderFragment(entry);
13268
- const dir = join12(opts.homeDir, PROVIDER_CONTEXT_DIR);
13269
- if (!existsSync11(dir))
13368
+ const dir = join13(opts.homeDir, PROVIDER_CONTEXT_DIR);
13369
+ if (!existsSync12(dir))
13270
13370
  mkdirSync5(dir, { recursive: true });
13271
13371
  const filename = `${entry ? entry.key : "invariant"}.md`;
13272
- const fragmentPath2 = join12(dir, filename);
13372
+ const fragmentPath2 = join13(dir, filename);
13273
13373
  const fragmentSha256 = sha2569(content);
13274
13374
  writeFileSync4(fragmentPath2, content, "utf8");
13275
- const manifestPath = join12(dir, PROVIDER_CONTEXT_MANIFEST);
13375
+ const manifestPath = join13(dir, PROVIDER_CONTEXT_MANIFEST);
13276
13376
  let manifest = { schema: PROVIDER_CONTEXT_SCHEMA, fragments: {} };
13277
13377
  try {
13278
- if (existsSync11(manifestPath)) {
13378
+ if (existsSync12(manifestPath)) {
13279
13379
  const parsed = JSON.parse(readFileSync10(manifestPath, "utf8"));
13280
13380
  if (parsed && typeof parsed === "object")
13281
13381
  manifest = parsed;
@@ -13387,9 +13487,9 @@ var PG_MIGRATIONS = [
13387
13487
  ];
13388
13488
  // src/lib/station-profile.ts
13389
13489
  import { spawnSync as spawnSync2 } from "child_process";
13390
- import { existsSync as existsSync12, lstatSync as lstatSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync11, readdirSync, writeFileSync as writeFileSync5 } from "fs";
13391
- import { arch as osArch, homedir as homedir8, hostname as osHostname, platform as osPlatform, userInfo as osUserInfo } from "os";
13392
- import { dirname as dirname8, join as join13, resolve as resolve9 } from "path";
13490
+ import { existsSync as existsSync13, lstatSync as lstatSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync11, readdirSync, writeFileSync as writeFileSync5 } from "fs";
13491
+ import { arch as osArch, homedir as homedir9, hostname as osHostname, platform as osPlatform, userInfo as osUserInfo } from "os";
13492
+ import { dirname as dirname8, join as join14 } from "path";
13393
13493
  var STATION_PROFILE_CACHE_FILENAME = "station-profile.md";
13394
13494
  var STATION_PROFILE_SOURCE_ID = "station-profile";
13395
13495
  var STATION_PROFILE_LAYER = "machine";
@@ -13399,22 +13499,21 @@ var STATION_PROFILE_FULL_NAMES_MAX = 6;
13399
13499
  var STATION_PROFILE_PRIMARY_SCOPE = "@hasna";
13400
13500
  var MACHINES_MANIFEST_PATH_ENV = "HASNA_MACHINES_MANIFEST_PATH";
13401
13501
  var BUN_INSTALL_ENV = "BUN_INSTALL";
13402
- function homeDir2(env = process.env) {
13403
- return env["HOME"] || env["USERPROFILE"] || homedir8();
13502
+ function homeDir3(env = process.env) {
13503
+ return env["HOME"] || env["USERPROFILE"] || homedir9();
13404
13504
  }
13405
13505
  function getStationProfileCachePath(env = process.env) {
13406
- const root = env["HASNA_CONFIGS_HOME"] || join13(homeDir2(env), ".hasna", "instructions");
13407
- return join13(resolve9(root), STATION_PROFILE_CACHE_FILENAME);
13506
+ return join14(getRawStoreRoot(env), STATION_PROFILE_CACHE_FILENAME);
13408
13507
  }
13409
13508
  function getMachinesManifestPath(env = process.env) {
13410
- return env[MACHINES_MANIFEST_PATH_ENV] || join13(homeDir2(env), ".hasna", "machines", "machines.json");
13509
+ return env[MACHINES_MANIFEST_PATH_ENV] || join14(homeDir3(env), ".hasna", "machines", "machines.json");
13411
13510
  }
13412
13511
  function getBunGlobalModulesDir(env = process.env) {
13413
- return join13(env[BUN_INSTALL_ENV] || join13(homeDir2(env), ".bun"), "install", "global", "node_modules");
13512
+ return join14(env[BUN_INSTALL_ENV] || join14(homeDir3(env), ".bun"), "install", "global", "node_modules");
13414
13513
  }
13415
13514
  function readMachinesManifest(path) {
13416
13515
  try {
13417
- if (!existsSync12(path))
13516
+ if (!existsSync13(path))
13418
13517
  return null;
13419
13518
  const parsed = JSON.parse(readFileSync11(path, "utf8"));
13420
13519
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
@@ -13470,9 +13569,9 @@ function probeMachineStatus(machineId) {
13470
13569
  function resolveStationProfileMachine(env = process.env, options = {}) {
13471
13570
  const hostname2 = osHostname();
13472
13571
  const record = findLocalManifestMachine(readMachinesManifest(getMachinesManifestPath(env)), hostname2);
13473
- const home = homeDir2(env);
13572
+ const home = homeDir3(env);
13474
13573
  const platform = stringField(record, "platform") ?? osPlatform();
13475
- const workspacePath = stringField(record, "workspacePath") ?? join13(home, platform === "darwin" ? "Workspace" : "workspace");
13574
+ const workspacePath = stringField(record, "workspacePath") ?? join14(home, platform === "darwin" ? "Workspace" : "workspace");
13476
13575
  const machine = {
13477
13576
  id: stringField(record, "id") ?? hostname2,
13478
13577
  hostname: stringField(record, "hostname") ?? hostname2,
@@ -13489,9 +13588,9 @@ function resolveStationProfileMachine(env = process.env, options = {}) {
13489
13588
  return machine;
13490
13589
  }
13491
13590
  function scopedPackageNames(modulesDir, scope) {
13492
- const scopeDir = join13(modulesDir, scope);
13591
+ const scopeDir = join14(modulesDir, scope);
13493
13592
  try {
13494
- if (!existsSync12(scopeDir))
13593
+ if (!existsSync13(scopeDir))
13495
13594
  return null;
13496
13595
  return readdirNames(scopeDir).sort();
13497
13596
  } catch {
@@ -13501,7 +13600,7 @@ function scopedPackageNames(modulesDir, scope) {
13501
13600
  function readdirNames(dir) {
13502
13601
  return readdirSync(dir).filter((name) => {
13503
13602
  try {
13504
- return lstatSync5(join13(dir, name)).isDirectory();
13603
+ return lstatSync5(join14(dir, name)).isDirectory();
13505
13604
  } catch {
13506
13605
  return false;
13507
13606
  }
@@ -13511,7 +13610,7 @@ function resolveStationProfilePackages(env = process.env) {
13511
13610
  const modulesDir = getBunGlobalModulesDir(env);
13512
13611
  let scopeDirs;
13513
13612
  try {
13514
- if (!existsSync12(modulesDir))
13613
+ if (!existsSync13(modulesDir))
13515
13614
  return null;
13516
13615
  scopeDirs = readdirNames(modulesDir).filter((name) => name.startsWith("@") && name.toLowerCase().includes("hasna"));
13517
13616
  } catch {
@@ -13586,7 +13685,7 @@ function refreshStationProfile(options = {}) {
13586
13685
  const path = getStationProfileCachePath(env);
13587
13686
  const generatedAt = new Date().toISOString();
13588
13687
  if (!options.dryRun) {
13589
- const existing = existsSync12(path) ? readFileSync11(path, "utf8") : null;
13688
+ const existing = existsSync13(path) ? readFileSync11(path, "utf8") : null;
13590
13689
  if (existing !== content) {
13591
13690
  mkdirSync6(dirname8(path), { recursive: true });
13592
13691
  writeFileSync5(path, content, "utf8");
@@ -13605,7 +13704,7 @@ function refreshStationProfile(options = {}) {
13605
13704
  function readStationProfile(env = process.env) {
13606
13705
  const path = getStationProfileCachePath(env);
13607
13706
  try {
13608
- if (!existsSync12(path))
13707
+ if (!existsSync13(path))
13609
13708
  return null;
13610
13709
  return readFileSync11(path, "utf8");
13611
13710
  } catch {
@@ -13629,14 +13728,14 @@ function stationProfileSource(env = process.env) {
13629
13728
  // src/lib/session-apply.ts
13630
13729
  import { createHash as createHash10, randomUUID as randomUUID4 } from "crypto";
13631
13730
  import {
13632
- existsSync as existsSync13,
13731
+ existsSync as existsSync14,
13633
13732
  lstatSync as lstatSync6,
13634
13733
  mkdirSync as mkdirSync7,
13635
13734
  readFileSync as readFileSync12,
13636
13735
  readdirSync as readdirSync2,
13637
13736
  statSync as statSync5
13638
13737
  } from "fs";
13639
- import { dirname as dirname9, isAbsolute as isAbsolute4, join as join14, parse as parse5, relative as relative5, resolve as resolve10 } from "path";
13738
+ import { dirname as dirname9, isAbsolute as isAbsolute4, join as join15, parse as parse5, relative as relative5, resolve as resolve10 } from "path";
13640
13739
  class SessionApplyError extends Error {
13641
13740
  constructor(message) {
13642
13741
  super(message);
@@ -13767,7 +13866,7 @@ function assertClaudeAuthorityStillClear(plan, targetHome, ownedClaudeAuthoritie
13767
13866
  throw new SessionApplyError(`Claude authority changed after planning; refusing to apply: ${summary}`);
13768
13867
  }
13769
13868
  function ensureSessionTargetHome(targetHome) {
13770
- if (!existsSync13(targetHome))
13869
+ if (!existsSync14(targetHome))
13771
13870
  mkdirSync7(targetHome, { recursive: true, mode: 448 });
13772
13871
  assertSafeTargetHome(targetHome);
13773
13872
  }
@@ -13790,7 +13889,7 @@ function checkSessionRenderDrift(targetHome, manifestPath) {
13790
13889
  const drifted = [];
13791
13890
  for (const file of previousManifest.files) {
13792
13891
  const target = resolveManifestRelativePath(file.relativePath, safeTargetHome);
13793
- if (!existsSync13(target)) {
13892
+ if (!existsSync14(target)) {
13794
13893
  missing.push({
13795
13894
  path: target,
13796
13895
  relativePath: file.relativePath,
@@ -13942,7 +14041,7 @@ function requiredRestoreHash(file) {
13942
14041
  }
13943
14042
  function readSessionRenderSnapshot(snapshotPath) {
13944
14043
  const resolved = resolve10(snapshotPath);
13945
- if (!existsSync13(resolved))
14044
+ if (!existsSync14(resolved))
13946
14045
  throw new SessionApplyError(`Session snapshot not found: ${snapshotPath}`);
13947
14046
  const stat = lstatSync6(resolved);
13948
14047
  if (stat.isSymbolicLink() || !stat.isFile()) {
@@ -14209,7 +14308,7 @@ function resolveSnapshotFilePath(relativePath, recordedPath, targetHome) {
14209
14308
  }
14210
14309
  function planFileResult(plan, file, targetHome, previousHashes, previousManifest, options) {
14211
14310
  const target = resolvePlannedFilePath(plan, file, targetHome);
14212
- const previousContent = existsSync13(target) ? readFileSync12(target, "utf-8") : null;
14311
+ const previousContent = existsSync14(target) ? readFileSync12(target, "utf-8") : null;
14213
14312
  const previousSha256 = previousContent === null ? null : sha25610(previousContent);
14214
14313
  const previouslyManaged = isPreviouslyManaged(file, previousSha256, previousHashes, previousManifest);
14215
14314
  const changed = previousContent !== file.content;
@@ -14308,7 +14407,7 @@ function planStaleFileResults(plan, targetHome, previousManifest, currentRelativ
14308
14407
  }
14309
14408
  function planStaleFileResult(file, targetHome, options) {
14310
14409
  const target = resolveManifestRelativePath(file.relativePath, targetHome);
14311
- if (!existsSync13(target))
14410
+ if (!existsSync14(target))
14312
14411
  return null;
14313
14412
  const previousContent = readFileSync12(target, "utf-8");
14314
14413
  const previousSha256 = sha25610(previousContent);
@@ -14376,7 +14475,7 @@ function resolveManifestRelativePath(relativePath, targetHome) {
14376
14475
  return target;
14377
14476
  }
14378
14477
  function readPreviousManifest(path) {
14379
- if (!existsSync13(path))
14478
+ if (!existsSync14(path))
14380
14479
  return null;
14381
14480
  try {
14382
14481
  const parsed = JSON.parse(readFileSync12(path, "utf-8"));
@@ -14418,7 +14517,7 @@ function assertExpectedSessionFileHash(path, targetHome, expectedHash) {
14418
14517
  }
14419
14518
  function currentSessionFileHash(path, targetHome) {
14420
14519
  assertNoSymlinkSegments2(targetHome, path);
14421
- if (!existsSync13(path))
14520
+ if (!existsSync14(path))
14422
14521
  return null;
14423
14522
  const stat = lstatSync6(path);
14424
14523
  if (stat.isSymbolicLink() || !stat.isFile()) {
@@ -14433,7 +14532,7 @@ function requiredPreviousHash(result) {
14433
14532
  return result.previousSha256;
14434
14533
  }
14435
14534
  function writeSessionSnapshot(plan, targetHome, manifestPath, results, previousManifest, coordination, allowPortableFallback, forcePortableFileOps) {
14436
- const existingFiles = results.filter((result) => result.action === "update" || result.action === "delete").filter((result) => existsSync13(result.path)).map((result) => {
14535
+ const existingFiles = results.filter((result) => result.action === "update" || result.action === "delete").filter((result) => existsSync14(result.path)).map((result) => {
14437
14536
  const content = readFileSync12(result.path, "utf-8");
14438
14537
  return {
14439
14538
  path: result.path,
@@ -14505,7 +14604,7 @@ function assertSafeTargetHome(targetHome) {
14505
14604
  throw new SessionApplyError(`Session target home cannot be the filesystem root: ${targetHome}`);
14506
14605
  }
14507
14606
  assertNoSymlinkAncestors3(normalized);
14508
- if (existsSync13(normalized) && lstatSync6(normalized).isSymbolicLink()) {
14607
+ if (existsSync14(normalized) && lstatSync6(normalized).isSymbolicLink()) {
14509
14608
  throw new SessionApplyError(`Session target home cannot be a symlink: ${normalized}`);
14510
14609
  }
14511
14610
  return normalized;
@@ -14515,8 +14614,8 @@ function assertNoSymlinkSegments2(root, target) {
14515
14614
  const rel = relative5(root, target);
14516
14615
  let current = root;
14517
14616
  for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
14518
- current = join14(current, segment);
14519
- if (existsSync13(current) && lstatSync6(current).isSymbolicLink()) {
14617
+ current = join15(current, segment);
14618
+ if (existsSync14(current) && lstatSync6(current).isSymbolicLink()) {
14520
14619
  throw new SessionApplyError(`Session apply path uses a symlink: ${current}`);
14521
14620
  }
14522
14621
  }
@@ -14527,8 +14626,8 @@ function assertNoSymlinkAncestors3(path) {
14527
14626
  let current = parsed.root;
14528
14627
  const rel = relative5(parsed.root, normalized);
14529
14628
  for (const segment of rel.split(/[\\/]+/).filter(Boolean)) {
14530
- current = join14(current, segment);
14531
- if (!existsSync13(current))
14629
+ current = join15(current, segment);
14630
+ if (!existsSync14(current))
14532
14631
  return;
14533
14632
  if (lstatSync6(current).isSymbolicLink()) {
14534
14633
  throw new SessionApplyError(`Session apply path uses a symlink ancestor: ${current}`);
@@ -14839,13 +14938,13 @@ async function ensureDangerousOperationGuardStandardConfig(store = resolveConfig
14839
14938
  }
14840
14939
  }
14841
14940
  // src/lib/sync.ts
14842
- import { existsSync as existsSync15, readdirSync as readdirSync4, readFileSync as readFileSync14 } from "fs";
14843
- import { basename as basename6, extname as extname3, join as join16 } from "path";
14941
+ import { existsSync as existsSync16, readdirSync as readdirSync4, readFileSync as readFileSync14 } from "fs";
14942
+ import { basename as basename6, extname as extname3, join as join17 } from "path";
14844
14943
 
14845
14944
  // src/lib/sync-dir.ts
14846
- import { existsSync as existsSync14, readdirSync as readdirSync3, readFileSync as readFileSync13, statSync as statSync6 } from "fs";
14847
- import { join as join15, relative as relative6 } from "path";
14848
- import { homedir as homedir9 } from "os";
14945
+ import { existsSync as existsSync15, readdirSync as readdirSync3, readFileSync as readFileSync13, statSync as statSync6 } from "fs";
14946
+ import { join as join16, relative as relative6 } from "path";
14947
+ import { homedir as homedir10 } from "os";
14849
14948
  var SKIP = [".db", ".db-shm", ".db-wal", ".log", ".lock", ".DS_Store", "node_modules", ".git"];
14850
14949
  function shouldSkip(p) {
14851
14950
  return SKIP.some((s) => p.includes(s));
@@ -14853,11 +14952,11 @@ function shouldSkip(p) {
14853
14952
  async function syncFromDir(dir, opts = {}) {
14854
14953
  const store = opts.store ?? resolveConfigStore();
14855
14954
  const absDir = expandPath(dir);
14856
- if (!existsSync14(absDir))
14955
+ if (!existsSync15(absDir))
14857
14956
  return { added: 0, updated: 0, unchanged: 0, skipped: [`Not found: ${absDir}`] };
14858
- const files = opts.recursive !== false ? walkDir(absDir) : readdirSync3(absDir).map((f) => join15(absDir, f)).filter((f) => statSync6(f).isFile());
14957
+ const files = opts.recursive !== false ? walkDir(absDir) : readdirSync3(absDir).map((f) => join16(absDir, f)).filter((f) => statSync6(f).isFile());
14859
14958
  const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
14860
- const home = homedir9();
14959
+ const home = homedir10();
14861
14960
  const allConfigs = await store.listConfigs();
14862
14961
  for (const file of files) {
14863
14962
  if (shouldSkip(file)) {
@@ -14892,7 +14991,7 @@ async function syncFromDir(dir, opts = {}) {
14892
14991
  }
14893
14992
  async function syncToDir(dir, opts = {}) {
14894
14993
  const store = opts.store ?? resolveConfigStore();
14895
- const home = homedir9();
14994
+ const home = homedir10();
14896
14995
  const absDir = expandPath(dir);
14897
14996
  const normalized = dir.startsWith("~/") ? dir : absDir.replace(home, "~");
14898
14997
  const configs = (await store.listConfigs()).filter((c) => c.target_path && (c.target_path.startsWith(normalized) || c.target_path.startsWith(absDir)));
@@ -14916,7 +15015,7 @@ async function syncToDir(dir, opts = {}) {
14916
15015
  }
14917
15016
  function walkDir(dir, files = []) {
14918
15017
  for (const entry of readdirSync3(dir, { withFileTypes: true })) {
14919
- const full = join15(dir, entry.name);
15018
+ const full = join16(dir, entry.name);
14920
15019
  if (shouldSkip(full))
14921
15020
  continue;
14922
15021
  if (entry.isDirectory())
@@ -14977,7 +15076,7 @@ function isGeneratedOutputTarget2(config, owners) {
14977
15076
  return !!ownerIds && !ownerIds.has(config.id);
14978
15077
  }
14979
15078
  function hasClaudePromptSource() {
14980
- return existsSync15(expandPath("~/.claude/CLAUDE.md"));
15079
+ return existsSync16(expandPath("~/.claude/CLAUDE.md"));
14981
15080
  }
14982
15081
  function hasClaudeRuleSourceForCursorTarget(targetPath) {
14983
15082
  const absoluteTargetPath = expandPath(targetPath);
@@ -14985,7 +15084,7 @@ function hasClaudeRuleSourceForCursorTarget(targetPath) {
14985
15084
  if (!absoluteTargetPath.startsWith(`${absolutePrefix}/`) || !absoluteTargetPath.endsWith(".mdc"))
14986
15085
  return false;
14987
15086
  const stem = basename6(absoluteTargetPath, ".mdc");
14988
- return existsSync15(expandPath(`~/.claude/rules/${stem}.md`)) || existsSync15(expandPath(`~/.claude/rules/${stem}.mdc`));
15087
+ return existsSync16(expandPath(`~/.claude/rules/${stem}.md`)) || existsSync16(expandPath(`~/.claude/rules/${stem}.mdc`));
14989
15088
  }
14990
15089
  function isKnownGeneratedTargetPath(targetPath) {
14991
15090
  const normalizedTargetPath = normalizeTargetPath(targetPath);
@@ -15050,8 +15149,8 @@ async function syncProject(opts) {
15050
15149
  const allConfigs = await store.listConfigs();
15051
15150
  const machine = detectMachineContext();
15052
15151
  for (const pf of PROJECT_CONFIG_FILES) {
15053
- const abs = join16(absDir, pf.file);
15054
- if (!existsSync15(abs))
15152
+ const abs = join17(absDir, pf.file);
15153
+ if (!existsSync16(abs))
15055
15154
  continue;
15056
15155
  try {
15057
15156
  const rawContent = readFileSync14(abs, "utf-8");
@@ -15083,19 +15182,19 @@ async function syncProject(opts) {
15083
15182
  }
15084
15183
  }
15085
15184
  for (const ruleDir of [
15086
- { dir: join16(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
15087
- { dir: join16(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
15088
- { dir: join16(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
15089
- { dir: join16(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
15090
- { dir: join16(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
15091
- { dir: join16(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
15092
- { dir: join16(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
15185
+ { dir: join17(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
15186
+ { dir: join17(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
15187
+ { dir: join17(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
15188
+ { dir: join17(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
15189
+ { dir: join17(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
15190
+ { dir: join17(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
15191
+ { dir: join17(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
15093
15192
  ]) {
15094
- if (!existsSync15(ruleDir.dir))
15193
+ if (!existsSync16(ruleDir.dir))
15095
15194
  continue;
15096
15195
  const mdFiles = readdirSync4(ruleDir.dir).filter((f) => f.endsWith(".md") || f.endsWith(".mdc"));
15097
15196
  for (const f of mdFiles) {
15098
- const abs = join16(ruleDir.dir, f);
15197
+ const abs = join17(ruleDir.dir, f);
15099
15198
  const raw = readFileSync14(abs, "utf-8");
15100
15199
  const redacted = redactContent(raw, "markdown");
15101
15200
  const machineAware = templateizeMachineContent(redacted.content, machine);
@@ -15135,14 +15234,14 @@ async function syncKnown(opts = {}) {
15135
15234
  for (const known of targets) {
15136
15235
  if (known.rulesDir) {
15137
15236
  const absDir = expandPath(known.rulesDir);
15138
- if (!existsSync15(absDir)) {
15237
+ if (!existsSync16(absDir)) {
15139
15238
  result.skipped.push(known.rulesDir);
15140
15239
  continue;
15141
15240
  }
15142
15241
  const extensions = known.rulesExtensions ?? [".md", ".mdc"];
15143
15242
  const ruleFiles = readdirSync4(absDir).filter((f) => extensions.some((ext) => f.endsWith(ext)));
15144
15243
  for (const f of ruleFiles) {
15145
- const abs2 = join16(absDir, f);
15244
+ const abs2 = join17(absDir, f);
15146
15245
  const targetPath = abs2.replace(home, "~");
15147
15246
  if (existingOutputOwners.has(normalizeTargetPath(targetPath)) || isKnownGeneratedTargetPath(targetPath)) {
15148
15247
  result.skipped.push(`${targetPath} (generated output)`);
@@ -15176,7 +15275,7 @@ async function syncKnown(opts = {}) {
15176
15275
  continue;
15177
15276
  }
15178
15277
  const abs = expandPath(known.path);
15179
- if (!existsSync15(abs)) {
15278
+ if (!existsSync16(abs)) {
15180
15279
  result.skipped.push(known.path);
15181
15280
  continue;
15182
15281
  }
@@ -15284,7 +15383,7 @@ function storedPlaceholderIsLiteralOnDisk(storedLine, diskLine) {
15284
15383
  }
15285
15384
  function buildDiff(expectedContent, targetPath, storedFormat, showSecrets) {
15286
15385
  const path = expandPath(targetPath);
15287
- if (!existsSync15(path))
15386
+ if (!existsSync16(path))
15288
15387
  return `(file not found on disk: ${path})`;
15289
15388
  const diskContent = readFileSync14(path, "utf-8");
15290
15389
  if (diskContent === expectedContent)
@@ -15444,15 +15543,15 @@ function detectFormat(filePath) {
15444
15543
  return "text";
15445
15544
  }
15446
15545
  // src/lib/export.ts
15447
- import { existsSync as existsSync16, mkdirSync as mkdirSync8, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "fs";
15448
- import { join as join17, resolve as resolve11 } from "path";
15546
+ import { existsSync as existsSync17, mkdirSync as mkdirSync8, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "fs";
15547
+ import { join as join18, resolve as resolve11 } from "path";
15449
15548
  import { tmpdir } from "os";
15450
15549
  async function exportConfigs(outputPath, opts = {}) {
15451
15550
  const store = opts.store ?? resolveConfigStore();
15452
15551
  const configs = await store.listConfigs(opts.filter);
15453
15552
  const absOutput = resolve11(outputPath);
15454
- const tmpDir = join17(tmpdir(), `configs-export-${Date.now()}`);
15455
- const contentsDir = join17(tmpDir, "contents");
15553
+ const tmpDir = join18(tmpdir(), `configs-export-${Date.now()}`);
15554
+ const contentsDir = join18(tmpDir, "contents");
15456
15555
  try {
15457
15556
  mkdirSync8(contentsDir, { recursive: true });
15458
15557
  const manifest = {
@@ -15460,10 +15559,10 @@ async function exportConfigs(outputPath, opts = {}) {
15460
15559
  exported_at: new Date().toISOString(),
15461
15560
  configs: configs.map(({ content: _content, ...meta }) => meta)
15462
15561
  };
15463
- writeFileSync6(join17(tmpDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
15562
+ writeFileSync6(join18(tmpDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
15464
15563
  for (const config of configs) {
15465
15564
  const fileName = `${config.slug}.${config.format === "text" ? "txt" : config.format}`;
15466
- writeFileSync6(join17(contentsDir, fileName), config.content, "utf-8");
15565
+ writeFileSync6(join18(contentsDir, fileName), config.content, "utf-8");
15467
15566
  }
15468
15567
  const proc = Bun.spawn(["tar", "czf", absOutput, "-C", tmpDir, "."], {
15469
15568
  stdout: "pipe",
@@ -15476,20 +15575,20 @@ async function exportConfigs(outputPath, opts = {}) {
15476
15575
  }
15477
15576
  return { path: absOutput, count: configs.length };
15478
15577
  } finally {
15479
- if (existsSync16(tmpDir)) {
15578
+ if (existsSync17(tmpDir)) {
15480
15579
  rmSync4(tmpDir, { recursive: true, force: true });
15481
15580
  }
15482
15581
  }
15483
15582
  }
15484
15583
  // src/lib/import.ts
15485
- import { existsSync as existsSync17, mkdirSync as mkdirSync9, readFileSync as readFileSync15, rmSync as rmSync5 } from "fs";
15486
- import { join as join18, resolve as resolve12 } from "path";
15584
+ import { existsSync as existsSync18, mkdirSync as mkdirSync9, readFileSync as readFileSync15, rmSync as rmSync5 } from "fs";
15585
+ import { join as join19, resolve as resolve12 } from "path";
15487
15586
  import { tmpdir as tmpdir2 } from "os";
15488
15587
  async function importConfigs(bundlePath, opts = {}) {
15489
15588
  const store = opts.store ?? resolveConfigStore();
15490
15589
  const conflict = opts.conflict ?? "skip";
15491
15590
  const absPath = resolve12(bundlePath);
15492
- const tmpDir = join18(tmpdir2(), `configs-import-${Date.now()}`);
15591
+ const tmpDir = join19(tmpdir2(), `configs-import-${Date.now()}`);
15493
15592
  const result = { created: 0, updated: 0, skipped: 0, errors: [] };
15494
15593
  try {
15495
15594
  mkdirSync9(tmpDir, { recursive: true });
@@ -15502,15 +15601,15 @@ async function importConfigs(bundlePath, opts = {}) {
15502
15601
  const stderr = await new Response(proc.stderr).text();
15503
15602
  throw new Error(`tar extraction failed: ${stderr}`);
15504
15603
  }
15505
- const manifestPath = join18(tmpDir, "manifest.json");
15506
- if (!existsSync17(manifestPath))
15604
+ const manifestPath = join19(tmpDir, "manifest.json");
15605
+ if (!existsSync18(manifestPath))
15507
15606
  throw new Error("Invalid bundle: missing manifest.json");
15508
15607
  const manifest = JSON.parse(readFileSync15(manifestPath, "utf-8"));
15509
15608
  for (const meta of manifest.configs) {
15510
15609
  try {
15511
15610
  const ext = meta.format === "text" ? "txt" : meta.format;
15512
- const contentFile = join18(tmpDir, "contents", `${meta.slug}.${ext}`);
15513
- const content = existsSync17(contentFile) ? readFileSync15(contentFile, "utf-8") : "";
15611
+ const contentFile = join19(tmpDir, "contents", `${meta.slug}.${ext}`);
15612
+ const content = existsSync18(contentFile) ? readFileSync15(contentFile, "utf-8") : "";
15514
15613
  let existing = null;
15515
15614
  try {
15516
15615
  existing = await store.getConfig(meta.slug);
@@ -15544,16 +15643,16 @@ async function importConfigs(bundlePath, opts = {}) {
15544
15643
  }
15545
15644
  return result;
15546
15645
  } finally {
15547
- if (existsSync17(tmpDir)) {
15646
+ if (existsSync18(tmpDir)) {
15548
15647
  rmSync5(tmpDir, { recursive: true, force: true });
15549
15648
  }
15550
15649
  }
15551
15650
  }
15552
15651
  // src/lib/package-manager-guard.ts
15553
15652
  import { execFileSync as execFileSync2 } from "child_process";
15554
- import { existsSync as existsSync18, lstatSync as lstatSync7, readdirSync as readdirSync5, readFileSync as readFileSync16 } from "fs";
15555
- import { homedir as homedir10 } from "os";
15556
- import { basename as basename7, dirname as dirname10, isAbsolute as isAbsolute5, join as join19, relative as relative7, resolve as resolve13 } from "path";
15653
+ import { existsSync as existsSync19, lstatSync as lstatSync7, readdirSync as readdirSync5, readFileSync as readFileSync16 } from "fs";
15654
+ import { homedir as homedir11 } from "os";
15655
+ import { basename as basename7, dirname as dirname10, isAbsolute as isAbsolute5, join as join20, relative as relative7, resolve as resolve13 } from "path";
15557
15656
  var SKIP_DIRS = new Set([
15558
15657
  ".git",
15559
15658
  "node_modules",
@@ -15595,7 +15694,7 @@ function scanPackageManagerSecrets(options = {}) {
15595
15694
  const findings = [];
15596
15695
  let scannedFiles = 0;
15597
15696
  for (const root of roots) {
15598
- if (!existsSync18(root))
15697
+ if (!existsSync19(root))
15599
15698
  continue;
15600
15699
  const stat = lstatSync7(root);
15601
15700
  if (stat.isFile()) {
@@ -15622,10 +15721,10 @@ function scanPackageManagerSecrets(options = {}) {
15622
15721
  }
15623
15722
  }
15624
15723
  if (options.includeHome) {
15625
- const home = homedir10();
15724
+ const home = homedir11();
15626
15725
  for (const name of HOME_FILES) {
15627
- const file = join19(home, name);
15628
- if (!existsSync18(file))
15726
+ const file = join20(home, name);
15727
+ if (!existsSync19(file))
15629
15728
  continue;
15630
15729
  const text = readTextFile(file);
15631
15730
  if (text === null)
@@ -15649,12 +15748,12 @@ function collectRepoFiles(root) {
15649
15748
  if (entry.isDirectory()) {
15650
15749
  if (SKIP_DIRS.has(entry.name))
15651
15750
  continue;
15652
- visit(join19(dir, entry.name));
15751
+ visit(join20(dir, entry.name));
15653
15752
  continue;
15654
15753
  }
15655
15754
  if (!entry.isFile())
15656
15755
  continue;
15657
- const file = join19(dir, entry.name);
15756
+ const file = join20(dir, entry.name);
15658
15757
  if (shouldScanRepoFile(file))
15659
15758
  out.push(file);
15660
15759
  }
@@ -15922,7 +16021,7 @@ function stripInlineComment(value) {
15922
16021
  return value.replace(/\s[#;].*$/, "").trim();
15923
16022
  }
15924
16023
  function displayPath(file, root) {
15925
- const home = homedir10();
16024
+ const home = homedir11();
15926
16025
  if (root === home && (file === home || file.startsWith(home + "/")))
15927
16026
  return "~/" + toPosix(relative7(home, file));
15928
16027
  if (isAbsolute5(root) && file.startsWith(root + "/"))