@hasna/skills 0.10.0 → 0.10.2

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/bin/index.js CHANGED
@@ -36868,7 +36868,7 @@ var package_default;
36868
36868
  var init_package = __esm(() => {
36869
36869
  package_default = {
36870
36870
  name: "@hasna/skills",
36871
- version: "0.10.0",
36871
+ version: "0.10.2",
36872
36872
  description: "Skills library for AI coding agents",
36873
36873
  type: "module",
36874
36874
  bin: {
@@ -48285,10 +48285,19 @@ var init_transport = __esm(() => {
48285
48285
  ]);
48286
48286
  });
48287
48287
 
48288
+ // src/lib/cli-credential-profile.ts
48289
+ function selectCliSkillsCredentialProfile(profile) {
48290
+ cliCredentialProfile = profile;
48291
+ }
48292
+ function selectedCliSkillsCredentialProfile() {
48293
+ return cliCredentialProfile;
48294
+ }
48295
+ var cliCredentialProfile;
48296
+
48288
48297
  // src/lib/instance-credentials.ts
48289
48298
  import { closeSync as closeSync5, constants as constants3, fstatSync as fstatSync5, lstatSync as lstatSync8, openSync as openSync5, readSync as readSync2 } from "fs";
48290
48299
  function selectedSkillsProfile(env3, explicit) {
48291
- const selected = explicit ?? env3.HASNA_PROFILE;
48300
+ const selected = explicit ?? selectedCliSkillsCredentialProfile() ?? env3.HASNA_PROFILE;
48292
48301
  if (selected === undefined)
48293
48302
  return null;
48294
48303
  const profile = selected.trim();
@@ -48574,11 +48583,13 @@ function snapshotSkillsEnvironment(env3) {
48574
48583
  return Object.freeze(snapshot);
48575
48584
  }
48576
48585
  function snapshotSkillsOptions(env3, options) {
48586
+ const profile = options.credentials?.profile ?? selectedCliSkillsCredentialProfile();
48587
+ const credentials = profile === undefined ? options.credentials : { ...options.credentials, profile };
48577
48588
  if (env3 !== process.env)
48578
- return options;
48579
- return { ...options, credentials: { ...options.credentials, keychain: {
48580
- ...options.credentials?.keychain,
48581
- enabled: options.credentials?.keychain?.enabled ?? true
48589
+ return credentials === options.credentials ? options : { ...options, credentials };
48590
+ return { ...options, credentials: { ...credentials, keychain: {
48591
+ ...credentials?.keychain,
48592
+ enabled: credentials?.keychain?.enabled ?? true
48582
48593
  } } };
48583
48594
  }
48584
48595
  function resolveSkillsFleetOrThrow(env3, options) {
@@ -48666,8 +48677,9 @@ async function resolveSkillsApiKey(env3 = process.env, options = {}) {
48666
48677
  }
48667
48678
  async function resolveSkillsConnection(env3 = process.env, options = {}) {
48668
48679
  const snapshotEnv = snapshotSkillsEnvironment(env3);
48669
- const assertFilesUnchanged = selectsSkillsLocalMode(snapshotEnv) ? () => {} : captureSkillsCredentialFiles(skillsProfileCredentialFiles(snapshotEnv, options.credentials?.profile));
48670
- const fleet = resolveSkillsFleet(snapshotEnv, snapshotSkillsOptions(env3, options));
48680
+ const resolvedOptions = snapshotSkillsOptions(env3, options);
48681
+ const assertFilesUnchanged = selectsSkillsLocalMode(snapshotEnv) ? () => {} : captureSkillsCredentialFiles(skillsProfileCredentialFiles(snapshotEnv, resolvedOptions.credentials?.profile));
48682
+ const fleet = resolveSkillsFleet(snapshotEnv, resolvedOptions);
48671
48683
  if (fleet.mode === "local" && env3 === process.env)
48672
48684
  noticeLocalSkillsMode();
48673
48685
  if (fleet.mode !== "hosted")
@@ -49692,7 +49704,9 @@ var init_skill_version = __esm(() => {
49692
49704
 
49693
49705
  // src/lib/selection-cache.ts
49694
49706
  import { createHash as createHash7, randomUUID as randomUUID3 } from "crypto";
49695
- import { closeSync as closeSync6, constants as constants4, fstatSync as fstatSync6, fsyncSync, lstatSync as lstatSync9, mkdirSync as mkdirSync3, openSync as openSync6, readSync as readSync3, renameSync, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
49707
+ import { spawnSync as spawnSync2 } from "child_process";
49708
+ import { closeSync as closeSync6, constants as constants4, fstatSync as fstatSync6, fsyncSync, lstatSync as lstatSync9, mkdirSync as mkdirSync3, openSync as openSync6, readFileSync as readFileSync10, readlinkSync as readlinkSync2, readSync as readSync3, renameSync, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
49709
+ import { hostname } from "os";
49696
49710
  import { dirname as dirname8, join as join16, parse as parse2, resolve as resolve8 } from "path";
49697
49711
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "util";
49698
49712
  function selectionCacheRoot(options = {}) {
@@ -49974,6 +49988,201 @@ function readSkillSessionSnapshot(sessionId, options = {}) {
49974
49988
  function skillSessionSnapshotBinding(snapshot) {
49975
49989
  return { sessionId: snapshot.sessionId, generation: snapshot.generation, receiptSha256: snapshot.receiptSha256 };
49976
49990
  }
49991
+ function localBootId() {
49992
+ try {
49993
+ if (process.platform === "linux") {
49994
+ const value = readFileSync10("/proc/sys/kernel/random/boot_id", "utf8").trim();
49995
+ return /^[a-f0-9-]{36}$/i.test(value) ? value : null;
49996
+ }
49997
+ if (process.platform === "darwin") {
49998
+ const result2 = spawnSync2("/usr/sbin/sysctl", ["-n", "kern.boottime"], { encoding: "utf8", timeout: 3000, env: { LC_ALL: "C" } });
49999
+ if (result2.status !== 0 || result2.error)
50000
+ return null;
50001
+ const seconds = /\bsec\s*=\s*(\d+)\b/.exec(result2.stdout)?.[1];
50002
+ return seconds ? `darwin:${seconds}` : null;
50003
+ }
50004
+ } catch {}
50005
+ return null;
50006
+ }
50007
+ function processStart(pid) {
50008
+ if (!Number.isSafeInteger(pid) || pid <= 0)
50009
+ return { state: "unknown" };
50010
+ if (process.platform === "linux") {
50011
+ try {
50012
+ const stat = readFileSync10(`/proc/${pid}/stat`, "utf8");
50013
+ const close = stat.lastIndexOf(")");
50014
+ const start = close < 0 ? undefined : stat.slice(close + 2).trim().split(/\s+/)[19];
50015
+ return start && /^\d+$/.test(start) ? { state: "alive", start: `linux:${start}` } : { state: "unknown" };
50016
+ } catch (error) {
50017
+ return { state: error.code === "ENOENT" ? "absent" : "unknown" };
50018
+ }
50019
+ }
50020
+ if (process.platform === "darwin") {
50021
+ const result2 = spawnSync2("/bin/ps", ["-p", String(pid), "-o", "lstart="], { encoding: "utf8", timeout: 3000, env: { LC_ALL: "C" } });
50022
+ if (result2.error || result2.signal)
50023
+ return { state: "unknown" };
50024
+ const start = result2.stdout.trim();
50025
+ if (result2.status === 1 && !start && !result2.stderr.trim())
50026
+ return { state: "absent" };
50027
+ return result2.status === 0 && start ? { state: "alive", start: `darwin:${start}` } : { state: "unknown" };
50028
+ }
50029
+ return { state: "unknown" };
50030
+ }
50031
+ function localLockIdentity() {
50032
+ const bootId = localBootId(), owner = processStart(process.pid);
50033
+ if (!bootId || owner.state !== "alive")
50034
+ return null;
50035
+ let pidNamespace;
50036
+ if (process.platform === "linux") {
50037
+ try {
50038
+ pidNamespace = readlinkSync2("/proc/self/ns/pid");
50039
+ } catch {
50040
+ return null;
50041
+ }
50042
+ if (!/^pid:\[\d+\]$/.test(pidNamespace))
50043
+ return null;
50044
+ }
50045
+ return { host: hostname(), bootId, pidNamespace, processStart: owner.start };
50046
+ }
50047
+ function readSessionLock(sessionId, options) {
50048
+ const path = `${sessionReceiptPath(sessionId, options)}.write-lock`;
50049
+ const before2 = lstatSync9(path, { throwIfNoEntry: false });
50050
+ if (!before2)
50051
+ return null;
50052
+ if (!before2.isFile() || before2.nlink !== 1 || process.getuid && before2.uid !== process.getuid()) {
50053
+ throw new SkillSelectionError("SESSION_WRITE_LOCKED", "The session lock is not a private regular file; recovery requires review.");
50054
+ }
50055
+ const bytes = readRegularFile(path, SESSION_LOCK_MAX_BYTES);
50056
+ const after2 = lstatSync9(path, { throwIfNoEntry: false });
50057
+ if (!bytes || !after2?.isFile() || before2.dev !== after2.dev || before2.ino !== after2.ino || before2.mtimeMs !== after2.mtimeMs) {
50058
+ throw new SkillSelectionError("SESSION_WRITE_LOCKED", "The session lock changed during inspection; recovery requires review.");
50059
+ }
50060
+ let marker;
50061
+ try {
50062
+ marker = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
50063
+ } catch {
50064
+ throw new SkillSelectionError("SESSION_WRITE_LOCKED", "The session lock is unreadable; recovery requires review.");
50065
+ }
50066
+ if (!marker || ![1, 2].includes(marker.schemaVersion) || marker.sessionId !== sessionId || !/^[a-f0-9-]{36}$/i.test(marker.operationId) || !Number.isSafeInteger(marker.pid) || marker.pid <= 0 || marker.schemaVersion === 2 && (!marker.host || !marker.bootId || !marker.processStart || process.platform === "linux" && !marker.pidNamespace)) {
50067
+ throw new SkillSelectionError("SESSION_WRITE_LOCKED", "The session lock has invalid ownership metadata; recovery requires review.");
50068
+ }
50069
+ return { path, bytes, marker, sha256: sha256Hex(bytes), dev: after2.dev, ino: after2.ino, mtimeMs: after2.mtimeMs };
50070
+ }
50071
+ function writerIsGone(lock, explicitLocalHost) {
50072
+ if (Date.now() - lock.mtimeMs < SESSION_LOCK_MIN_AGE_MS)
50073
+ return false;
50074
+ const owner = processStart(lock.marker.pid);
50075
+ if (owner.state === "unknown")
50076
+ return false;
50077
+ if (lock.marker.schemaVersion === 1)
50078
+ return explicitLocalHost && owner.state === "absent";
50079
+ const local = localLockIdentity();
50080
+ if (!local || lock.marker.host !== local.host || lock.marker.bootId !== local.bootId || lock.marker.pidNamespace !== local.pidNamespace)
50081
+ return false;
50082
+ return owner.state === "absent" || owner.state === "alive" && owner.start !== lock.marker.processStart;
50083
+ }
50084
+ function lockReviewDigest(lock, receipt) {
50085
+ return hash({
50086
+ sessionId: lock.marker.sessionId,
50087
+ lockSha256: lock.sha256,
50088
+ lockDev: lock.dev,
50089
+ lockIno: lock.ino,
50090
+ lockMtimeMs: lock.mtimeMs,
50091
+ receiptSha256: receipt?.sha256 ?? null,
50092
+ receiptGeneration: receipt?.generation ?? null
50093
+ });
50094
+ }
50095
+ function inspectSessionWriteLock(sessionId, options = {}) {
50096
+ const receipt = readSkillSessionSnapshotIfExists(sessionId, options), lock = readSessionLock(sessionId, options);
50097
+ if (!lock)
50098
+ throw new SkillSelectionError("SESSION_WRITE_LOCK_NOT_FOUND", "The session has no write lock to recover.");
50099
+ return {
50100
+ sessionId,
50101
+ schemaVersion: lock.marker.schemaVersion,
50102
+ pid: lock.marker.pid,
50103
+ lockSha256: lock.sha256,
50104
+ lockMtime: new Date(lock.mtimeMs).toISOString(),
50105
+ receiptSha256: receipt?.sha256 ?? null,
50106
+ receiptGeneration: receipt?.generation ?? null,
50107
+ reviewDigest: lockReviewDigest(lock, receipt),
50108
+ hostBound: lock.marker.schemaVersion === 2
50109
+ };
50110
+ }
50111
+ function archiveSessionLock(lock, receipt, explicitLocalHost) {
50112
+ const guardPath = `${lock.path}.recovery-guard`;
50113
+ let guardFd;
50114
+ try {
50115
+ guardFd = openSync6(guardPath, constants4.O_WRONLY | constants4.O_CREAT | constants4.O_EXCL | constants4.O_NOFOLLOW, 384);
50116
+ } catch (error) {
50117
+ if (error.code === "EEXIST")
50118
+ return null;
50119
+ throw error;
50120
+ }
50121
+ const guardStat = fstatSync6(guardFd);
50122
+ try {
50123
+ writeFileSync3(guardFd, `${JSON.stringify({ schemaVersion: 1, pid: process.pid, operationId: randomUUID3() })}
50124
+ `);
50125
+ fsyncSync(guardFd);
50126
+ const cacheOptions = { cacheDir: dirname8(dirname8(lock.path)) };
50127
+ const current = readSessionLock(lock.marker.sessionId, cacheOptions);
50128
+ if (!current || current.dev !== lock.dev || current.ino !== lock.ino || current.sha256 !== lock.sha256 || current.mtimeMs !== lock.mtimeMs || !writerIsGone(current, explicitLocalHost))
50129
+ return null;
50130
+ const currentReceipt = readSkillSessionSnapshotIfExists(lock.marker.sessionId, cacheOptions);
50131
+ if (currentReceipt?.sha256 !== receipt?.sha256 || currentReceipt?.generation !== receipt?.generation)
50132
+ return null;
50133
+ const directory = join16(dirname8(dirname8(lock.path)), "session-lock-recoveries", randomUUID3());
50134
+ const archivePath = join16(directory, "original.write-lock");
50135
+ const recordPath = join16(directory, "recovery.json");
50136
+ assertRegularPath(archivePath, true);
50137
+ archiveBytes(recordPath, Buffer.from(`${JSON.stringify({
50138
+ schemaVersion: 1,
50139
+ sessionId: lock.marker.sessionId,
50140
+ originalPath: lock.path,
50141
+ lockSha256: lock.sha256,
50142
+ lockMtime: new Date(lock.mtimeMs).toISOString(),
50143
+ lockPid: lock.marker.pid,
50144
+ receiptSha256: receipt?.sha256 ?? null,
50145
+ receiptGeneration: receipt?.generation ?? null,
50146
+ status: "prepared"
50147
+ })}
50148
+ `));
50149
+ syncDirectory(directory);
50150
+ syncDirectory(dirname8(directory));
50151
+ const finalLock = readSessionLock(lock.marker.sessionId, cacheOptions);
50152
+ if (!finalLock || finalLock.dev !== lock.dev || finalLock.ino !== lock.ino || finalLock.sha256 !== lock.sha256 || readSkillSessionSnapshotIfExists(lock.marker.sessionId, cacheOptions)?.sha256 !== receipt?.sha256)
50153
+ return null;
50154
+ let moved = false;
50155
+ try {
50156
+ renameSync(lock.path, archivePath);
50157
+ moved = true;
50158
+ syncDirectory(directory);
50159
+ syncDirectory(dirname8(lock.path));
50160
+ if (sha256Hex(readRegularFile(archivePath, SESSION_LOCK_MAX_BYTES)) !== lock.sha256) {
50161
+ throw new Error("Archived lock bytes changed");
50162
+ }
50163
+ } catch (error) {
50164
+ if (moved)
50165
+ throw new SkillSelectionError("SESSION_LOCK_RECOVERY_INCOMPLETE", "The lock moved, but durable recovery could not be confirmed; inspect the preserved recovery directory and session receipt.");
50166
+ throw error;
50167
+ }
50168
+ return archivePath;
50169
+ } finally {
50170
+ closeSync6(guardFd);
50171
+ const current = lstatSync9(guardPath, { throwIfNoEntry: false });
50172
+ if (current?.isFile() && current.dev === guardStat.dev && current.ino === guardStat.ino)
50173
+ unlinkSync(guardPath);
50174
+ }
50175
+ }
50176
+ function recoverSessionWriteLock(sessionId, reviewDigest, options = {}) {
50177
+ const receipt = readSkillSessionSnapshotIfExists(sessionId, options), lock = readSessionLock(sessionId, options);
50178
+ if (!lock || lockReviewDigest(lock, receipt) !== reviewDigest) {
50179
+ throw new SkillSelectionError("SESSION_LOCK_REVIEW_CHANGED", "The lock or receipt changed after review; inspect the session lock again.");
50180
+ }
50181
+ const archivePath = archiveSessionLock(lock, receipt, true);
50182
+ if (!archivePath)
50183
+ throw new SkillSelectionError("SESSION_WRITE_LOCKED", "The lock is live, too recent, or changed during recovery; leave it in place and inspect again.");
50184
+ return archivePath;
50185
+ }
49977
50186
  function withSessionWriteLocks(sessionIds, options, action) {
49978
50187
  const operationId = randomUUID3();
49979
50188
  const locks = [...new Set(sessionIds)].map((sessionId) => ({ sessionId, path: `${sessionReceiptPath(sessionId, options)}.write-lock` })).sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
@@ -49993,13 +50202,30 @@ function withSessionWriteLocks(sessionIds, options, action) {
49993
50202
  try {
49994
50203
  fd = openSync6(lock.path, constants4.O_WRONLY | constants4.O_CREAT | constants4.O_EXCL | constants4.O_NOFOLLOW, 384);
49995
50204
  } catch (error) {
49996
- if (error.code === "EEXIST")
49997
- throw new SkillSelectionError("SESSION_WRITE_LOCKED", "Another Skills process owns a required session write lock; retry after it completes. A surviving lock requires explicit recovery review.");
49998
- throw error;
50205
+ if (error.code !== "EEXIST")
50206
+ throw error;
50207
+ try {
50208
+ const stale = readSessionLock(lock.sessionId, options);
50209
+ const receipt = stale && readSkillSessionSnapshotIfExists(lock.sessionId, options);
50210
+ if (stale?.marker.schemaVersion === 2 && writerIsGone(stale, false)) {
50211
+ archiveSessionLock(stale, receipt, false);
50212
+ }
50213
+ } catch (recoveryError) {
50214
+ if (recoveryError instanceof SkillSelectionError && recoveryError.code === "SESSION_LOCK_RECOVERY_INCOMPLETE")
50215
+ throw recoveryError;
50216
+ }
50217
+ try {
50218
+ fd = openSync6(lock.path, constants4.O_WRONLY | constants4.O_CREAT | constants4.O_EXCL | constants4.O_NOFOLLOW, 384);
50219
+ } catch (retryError) {
50220
+ if (retryError.code === "EEXIST")
50221
+ throw new SkillSelectionError("SESSION_WRITE_LOCKED", "Another Skills process owns a required session write lock; retry after it completes. A surviving legacy lock requires explicit recovery review.");
50222
+ throw retryError;
50223
+ }
49999
50224
  }
50000
50225
  const stat = fstatSync6(fd);
50001
50226
  owned.push({ path: lock.path, fd, dev: stat.dev, ino: stat.ino });
50002
- writeFileSync3(fd, `${JSON.stringify({ schemaVersion: 1, operationId, sessionId: lock.sessionId, pid: process.pid })}
50227
+ const identity4 = localLockIdentity();
50228
+ writeFileSync3(fd, `${JSON.stringify({ schemaVersion: identity4 ? 2 : 1, operationId, sessionId: lock.sessionId, pid: process.pid, ...identity4 })}
50003
50229
  `);
50004
50230
  }
50005
50231
  return action(assertOwned);
@@ -50116,7 +50342,7 @@ function replaceSkillSession(expected, replacement, plan, options = {}, beforeCo
50116
50342
  return { archivePath, receiptPath, beforeSha256: before2.sha256, afterSha256 };
50117
50343
  });
50118
50344
  }
50119
- var SkillSelectionError, MAX_CACHED_PROFILE_AGE_MS, SELECTION_LOCK_FILE = "selection.lock.json";
50345
+ var SkillSelectionError, MAX_CACHED_PROFILE_AGE_MS, SELECTION_LOCK_FILE = "selection.lock.json", SESSION_LOCK_MAX_BYTES = 4096, SESSION_LOCK_MIN_AGE_MS = 30000;
50120
50346
  var init_selection_cache = __esm(() => {
50121
50347
  init_config();
50122
50348
  init_skill_bundle();
@@ -50174,7 +50400,7 @@ function capturePreparationProcess(child, platform2 = process.platform, signalGr
50174
50400
  }
50175
50401
 
50176
50402
  // src/lib/dependency-preparation.ts
50177
- import { constants as constants5, closeSync as closeSync7, fstatSync as fstatSync7, lstatSync as lstatSync10, mkdirSync as mkdirSync4, openSync as openSync7, readFileSync as readFileSync10, readdirSync as readdirSync5, rmdirSync, unlinkSync as unlinkSync2, ftruncateSync, writeSync } from "fs";
50403
+ import { constants as constants5, closeSync as closeSync7, fstatSync as fstatSync7, lstatSync as lstatSync10, mkdirSync as mkdirSync4, openSync as openSync7, readFileSync as readFileSync11, readdirSync as readdirSync5, rmdirSync, unlinkSync as unlinkSync2, ftruncateSync, writeSync } from "fs";
50178
50404
  import { join as join17 } from "path";
50179
50405
  function hasDependencyPreparationMarker(skillPath) {
50180
50406
  try {
@@ -50204,7 +50430,7 @@ function claimPreparation(skillPath) {
50204
50430
  return;
50205
50431
  if (!lstatSync10(state).isFile() || lstatSync10(state).isSymbolicLink() || lstatSync10(state).size > 1024)
50206
50432
  return;
50207
- const previous = JSON.parse(readFileSync10(state, "utf8"));
50433
+ const previous = JSON.parse(readFileSync11(state, "utf8"));
50208
50434
  if (previous.version !== 1 || previous.status !== "failed" || Object.keys(previous).length !== 2)
50209
50435
  return;
50210
50436
  }
@@ -50424,7 +50650,7 @@ var init_managed_policy = __esm(() => {
50424
50650
 
50425
50651
  // src/lib/agent-bridge.ts
50426
50652
  import { createHash as createHash8 } from "crypto";
50427
- import { lstatSync as lstatSync12, readFileSync as readFileSync11, readdirSync as readdirSync6 } from "fs";
50653
+ import { lstatSync as lstatSync12, readFileSync as readFileSync12, readdirSync as readdirSync6 } from "fs";
50428
50654
  import { join as join19 } from "path";
50429
50655
  function isOwnedCliBridge(path, expectedPaths) {
50430
50656
  if (!expectedPaths.includes(path))
@@ -50436,7 +50662,7 @@ function isOwnedCliBridge(path, expectedPaths) {
50436
50662
  return false;
50437
50663
  return Object.entries(CLI_BRIDGE_FILES).every(([name, content]) => {
50438
50664
  const file = join19(path, name), stat = lstatSync12(file);
50439
- return stat.isFile() && !stat.isSymbolicLink() && stat.size === Buffer.byteLength(content) && readFileSync11(file, "utf8") === content;
50665
+ return stat.isFile() && !stat.isSymbolicLink() && stat.size === Buffer.byteLength(content) && readFileSync12(file, "utf8") === content;
50440
50666
  });
50441
50667
  } catch {
50442
50668
  return false;
@@ -50810,7 +51036,7 @@ var init_claude_settings_witness = __esm(() => {
50810
51036
 
50811
51037
  // src/lib/agent-integration.ts
50812
51038
  import { createHash as createHash10, randomUUID as randomUUID5 } from "crypto";
50813
- import { existsSync as existsSync12, lstatSync as lstatSync14, statSync as statSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync12, readdirSync as readdirSync7, opendirSync as opendirSync3, readlinkSync as readlinkSync2, realpathSync as realpathSync3, renameSync as renameSync2, rmdirSync as rmdirSync2, writeFileSync as writeFileSync4, unlinkSync as unlinkSync3, chmodSync, openSync as openSync10, closeSync as closeSync10, fsyncSync as fsyncSync2, fstatSync as fstatSync10, readSync as readSync6, constants as constants8, linkSync } from "fs";
51039
+ import { existsSync as existsSync12, lstatSync as lstatSync14, statSync as statSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync13, readdirSync as readdirSync7, opendirSync as opendirSync3, readlinkSync as readlinkSync3, realpathSync as realpathSync3, renameSync as renameSync2, rmdirSync as rmdirSync2, writeFileSync as writeFileSync4, unlinkSync as unlinkSync3, chmodSync, openSync as openSync10, closeSync as closeSync10, fsyncSync as fsyncSync2, fstatSync as fstatSync10, readSync as readSync6, constants as constants8, linkSync } from "fs";
50814
51040
  import { dirname as dirname10, join as join20, resolve as resolve10, relative as relative4, isAbsolute as isAbsolute9, sep as sep4 } from "path";
50815
51041
  import { homedir as homedir3 } from "os";
50816
51042
  function assertSafePath(path) {
@@ -50830,7 +51056,7 @@ function readRootAlias(home, agent) {
50830
51056
  const stat = lstatSync14(alias, { throwIfNoEntry: false, bigint: true });
50831
51057
  if (!stat?.isSymbolicLink())
50832
51058
  throw new Error(`Agent root alias changed after planning: ${alias}`);
50833
- const link2 = readlinkSync2(alias), targetPath = resolve10(dirname10(alias), link2);
51059
+ const link2 = readlinkSync3(alias), targetPath = resolve10(dirname10(alias), link2);
50834
51060
  assertSafePath(targetPath);
50835
51061
  const targetStat = lstatSync14(targetPath, { throwIfNoEntry: false });
50836
51062
  if (!targetStat?.isDirectory())
@@ -51030,7 +51256,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
51030
51256
  throw new Error("Native skill discovery metadata limit exceeded");
51031
51257
  }
51032
51258
  function emptySiblingCacheAlias(path, parent) {
51033
- const link2 = readlinkSync2(path), target = resolve10(parent, link2);
51259
+ const link2 = readlinkSync3(path), target = resolve10(parent, link2);
51034
51260
  if (dirname10(target) !== parent || (isAbsolute9(link2) ? link2 !== target : dirname10(link2) !== "."))
51035
51261
  return false;
51036
51262
  if (!lstatSync14(target, { throwIfNoEntry: false })?.isDirectory())
@@ -51059,7 +51285,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
51059
51285
  const marker = join20(path, ".hasna-skills.json");
51060
51286
  if (existsSync12(marker)) {
51061
51287
  try {
51062
- managed = JSON.parse(readFileSync12(marker, "utf8")).managedBy === "@hasna/skills";
51288
+ managed = JSON.parse(readFileSync13(marker, "utf8")).managedBy === "@hasna/skills";
51063
51289
  } catch {}
51064
51290
  }
51065
51291
  const bridge = !vendor && isOwnedCliBridge(path, bridgePaths);
@@ -51132,7 +51358,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
51132
51358
  }
51133
51359
  function readOptional(path) {
51134
51360
  assertSafePath(path);
51135
- return existsSync12(path) ? readFileSync12(path, "utf8") : null;
51361
+ return existsSync12(path) ? readFileSync13(path, "utf8") : null;
51136
51362
  }
51137
51363
  function jsonObject(text2, path) {
51138
51364
  if (text2 === null)
@@ -51933,7 +52159,7 @@ import {
51933
52159
  lstatSync as lstatSync15,
51934
52160
  mkdirSync as mkdirSync7,
51935
52161
  mkdtempSync,
51936
- readFileSync as readFileSync13,
52162
+ readFileSync as readFileSync14,
51937
52163
  readdirSync as readdirSync9,
51938
52164
  renameSync as renameSync4,
51939
52165
  rmSync as rmSync2,
@@ -51950,7 +52176,7 @@ function hasSkillsOwnershipMarker(dir) {
51950
52176
  try {
51951
52177
  if (!lstatSync15(path).isFile())
51952
52178
  return false;
51953
- const marker = JSON.parse(readFileSync13(path, "utf8"));
52179
+ const marker = JSON.parse(readFileSync14(path, "utf8"));
51954
52180
  return isSkillsOwnershipMarker(marker);
51955
52181
  } catch {
51956
52182
  return false;
@@ -52158,7 +52384,7 @@ function writeManagedSkillDir(dir, skillMd, options) {
52158
52384
  if (dirExists && managed && hasSkillMd && !options.force && isPointerSkillMd(skillMd)) {
52159
52385
  let existingIsStub = false;
52160
52386
  try {
52161
- existingIsStub = isPointerSkillMd(readFileSync13(skillMdPath, "utf-8"));
52387
+ existingIsStub = isPointerSkillMd(readFileSync14(skillMdPath, "utf-8"));
52162
52388
  } catch {
52163
52389
  existingIsStub = false;
52164
52390
  }
@@ -52231,7 +52457,7 @@ function sourceSkillMd(skillPath, name, description, kind, preferBundledDocs = f
52231
52457
  if (kind === undefined || kind === "instruction" || preferBundledDocs) {
52232
52458
  const skillMdPath = join23(skillPath, "SKILL.md");
52233
52459
  if (existsSync14(skillMdPath))
52234
- return readFileSync13(skillMdPath, "utf-8");
52460
+ return readFileSync14(skillMdPath, "utf-8");
52235
52461
  }
52236
52462
  return pointerSkillMd(name, description);
52237
52463
  }
@@ -52281,7 +52507,7 @@ var init_skill_aliases = __esm(() => {
52281
52507
  });
52282
52508
 
52283
52509
  // src/lib/project-state.ts
52284
- import { existsSync as existsSync15, mkdirSync as mkdirSync8, readFileSync as readFileSync14, writeFileSync as writeFileSync7 } from "fs";
52510
+ import { existsSync as existsSync15, mkdirSync as mkdirSync8, readFileSync as readFileSync15, writeFileSync as writeFileSync7 } from "fs";
52285
52511
  import { join as join25 } from "path";
52286
52512
  function getProjectStateDir(targetDir = process.cwd()) {
52287
52513
  return join25(targetDir, SKILLS_PROJECT_DIR);
@@ -52294,7 +52520,7 @@ function loadProjectConfig(targetDir = process.cwd()) {
52294
52520
  if (!existsSync15(path))
52295
52521
  return null;
52296
52522
  try {
52297
- return normalizeProjectConfig(JSON.parse(readFileSync14(path, "utf-8")));
52523
+ return normalizeProjectConfig(JSON.parse(readFileSync15(path, "utf-8")));
52298
52524
  } catch {
52299
52525
  return null;
52300
52526
  }
@@ -52448,7 +52674,7 @@ __export(exports_installer, {
52448
52674
  AGENT_TARGETS: () => AGENT_TARGETS,
52449
52675
  AGENT_LABELS: () => AGENT_LABELS
52450
52676
  });
52451
- import { existsSync as existsSync16, readFileSync as readFileSync15, rmSync as rmSync3 } from "fs";
52677
+ import { existsSync as existsSync16, readFileSync as readFileSync16, rmSync as rmSync3 } from "fs";
52452
52678
  import { join as join26 } from "path";
52453
52679
  import { homedir as homedir5 } from "os";
52454
52680
  function getSkillPath(name) {
@@ -52547,7 +52773,7 @@ function createLocalSkillManifest(name, generateSkillMd) {
52547
52773
  let skillMd = "";
52548
52774
  const skillMdPath = join26(sourcePath, "SKILL.md");
52549
52775
  if (existsSync16(skillMdPath)) {
52550
- skillMd = readFileSync15(skillMdPath, "utf-8");
52776
+ skillMd = readFileSync16(skillMdPath, "utf-8");
52551
52777
  } else if (generateSkillMd) {
52552
52778
  skillMd = generateSkillMd(name) ?? "";
52553
52779
  } else {
@@ -52674,7 +52900,7 @@ function resolveAgentSkillMd(name, generateSkillMd) {
52674
52900
  const sourcePath = getSkillPath(name);
52675
52901
  const skillMdPath = join26(sourcePath, "SKILL.md");
52676
52902
  if (existsSync16(skillMdPath))
52677
- return readFileSync15(skillMdPath, "utf-8");
52903
+ return readFileSync16(skillMdPath, "utf-8");
52678
52904
  if (generateSkillMd)
52679
52905
  return generateSkillMd(name);
52680
52906
  return generateMinimalSkillMd(name);
@@ -52730,14 +52956,14 @@ function readBundledSkillVersion(name) {
52730
52956
  if (!existsSync16(pkgPath))
52731
52957
  return "unknown";
52732
52958
  try {
52733
- const pkg = JSON.parse(readFileSync15(pkgPath, "utf-8"));
52959
+ const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
52734
52960
  return pkg.version || "unknown";
52735
52961
  } catch {
52736
52962
  return "unknown";
52737
52963
  }
52738
52964
  }
52739
52965
  function readFileIfExists(path) {
52740
- return existsSync16(path) ? readFileSync15(path, "utf-8") : null;
52966
+ return existsSync16(path) ? readFileSync16(path, "utf-8") : null;
52741
52967
  }
52742
52968
  function loadProjectConfigCompat(targetDir) {
52743
52969
  return loadProjectConfig(targetDir);
@@ -52812,7 +53038,7 @@ __export(exports_skillinfo, {
52812
53038
  generateEnvExample: () => generateEnvExample,
52813
53039
  detectProjectSkills: () => detectProjectSkills
52814
53040
  });
52815
- import { existsSync as existsSync17, readFileSync as readFileSync16 } from "fs";
53041
+ import { existsSync as existsSync17, readFileSync as readFileSync17 } from "fs";
52816
53042
  import { join as join27 } from "path";
52817
53043
  function isInstructionSkillDir(skillPath, meta) {
52818
53044
  if (meta?.kind === "instruction")
@@ -52821,7 +53047,7 @@ function isInstructionSkillDir(skillPath, meta) {
52821
53047
  if (!existsSync17(skillMdPath))
52822
53048
  return false;
52823
53049
  try {
52824
- return parseSkillFrontmatter(readFileSync16(skillMdPath, "utf-8"))?.kind === "instruction";
53050
+ return parseSkillFrontmatter(readFileSync17(skillMdPath, "utf-8"))?.kind === "instruction";
52825
53051
  } catch {
52826
53052
  return false;
52827
53053
  }
@@ -52856,7 +53082,7 @@ function getSkillRequirements(name) {
52856
53082
  const meta = getSkill(name);
52857
53083
  let dependencies = {};
52858
53084
  try {
52859
- dependencies = JSON.parse(readFileSync16(join27(skillPath, "package.json"), "utf8")).dependencies || {};
53085
+ dependencies = JSON.parse(readFileSync17(join27(skillPath, "package.json"), "utf8")).dependencies || {};
52860
53086
  } catch {}
52861
53087
  return getSkillRequirementsFromContent(name, texts, dependencies, meta);
52862
53088
  }
@@ -52945,7 +53171,7 @@ async function runSkill(name, args, options = {}) {
52945
53171
  }
52946
53172
  let entryPoint2;
52947
53173
  try {
52948
- const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
53174
+ const pkg = JSON.parse(readFileSync17(pkgPath, "utf-8"));
52949
53175
  if (pkg.bin) {
52950
53176
  const binValues = Object.values(pkg.bin);
52951
53177
  entryPoint2 = binValues[0];
@@ -52990,7 +53216,7 @@ async function runSkill(name, args, options = {}) {
52990
53216
  function detectProjectSkills(cwd2 = process.cwd()) {
52991
53217
  let pkg;
52992
53218
  try {
52993
- pkg = JSON.parse(readFileSync16(join27(cwd2, "package.json"), "utf8"));
53219
+ pkg = JSON.parse(readFileSync17(join27(cwd2, "package.json"), "utf8"));
52994
53220
  } catch {
52995
53221
  return { detected: [], recommended: [] };
52996
53222
  }
@@ -53076,7 +53302,7 @@ function generateSkillMd(name) {
53076
53302
  const pkgPath = join27(skillPath, "package.json");
53077
53303
  if (existsSync17(pkgPath)) {
53078
53304
  try {
53079
- const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
53305
+ const pkg = JSON.parse(readFileSync17(pkgPath, "utf-8"));
53080
53306
  if (pkg.bin) {
53081
53307
  const binKeys = Object.keys(pkg.bin);
53082
53308
  if (binKeys.length > 0)
@@ -53150,7 +53376,7 @@ function extractEnvVars(text2) {
53150
53376
  function readIfExists(path) {
53151
53377
  try {
53152
53378
  if (existsSync17(path)) {
53153
- return readFileSync16(path, "utf-8");
53379
+ return readFileSync17(path, "utf-8");
53154
53380
  }
53155
53381
  } catch {}
53156
53382
  return null;
@@ -54995,7 +55221,7 @@ var init_codex_hook_discovery_recovery = __esm(() => {
54995
55221
 
54996
55222
  // src/lib/agent-discovery.ts
54997
55223
  import { createHash as createHash16 } from "crypto";
54998
- import { lstatSync as lstatSync20, readFileSync as readFileSync17, readdirSync as readdirSync10, realpathSync as realpathSync4 } from "fs";
55224
+ import { lstatSync as lstatSync20, readFileSync as readFileSync18, readdirSync as readdirSync10, realpathSync as realpathSync4 } from "fs";
54999
55225
  import { basename as basename8, dirname as dirname16, isAbsolute as isAbsolute15, join as join31, resolve as resolve15, sep as sep5 } from "path";
55000
55226
  import { isDeepStrictEqual as isDeepStrictEqual7 } from "util";
55001
55227
  function parseConfig(text3, path, toml = false) {
@@ -55027,7 +55253,7 @@ function read2(path, changes) {
55027
55253
  return null;
55028
55254
  if (!stat2.isFile() || stat2.size > 16 * 1024 * 1024)
55029
55255
  throw new Error(`Unsupported or oversized native discovery input: ${path}`);
55030
- return readFileSync17(path, "utf8");
55256
+ return readFileSync18(path, "utf8");
55031
55257
  }
55032
55258
  function projected(source, changes, budget = discoveryByteBudget()) {
55033
55259
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
@@ -56075,7 +56301,7 @@ __export(exports_registry, {
56075
56301
  CATEGORIES: () => CATEGORIES,
56076
56302
  BASIC_SKILL_NAMES: () => BASIC_SKILL_NAMES
56077
56303
  });
56078
- import { existsSync as existsSync19, readFileSync as readFileSync18, readdirSync as readdirSync12 } from "fs";
56304
+ import { existsSync as existsSync19, readFileSync as readFileSync19, readdirSync as readdirSync12 } from "fs";
56079
56305
  import { join as join34 } from "path";
56080
56306
  function isBasicSkillName(name) {
56081
56307
  return BASIC_SKILL_NAMES.includes(name);
@@ -56125,7 +56351,7 @@ function discoverSkillsInDir(dir, source = "custom") {
56125
56351
  continue;
56126
56352
  let content;
56127
56353
  try {
56128
- content = readFileSync18(skillMdPath, "utf-8");
56354
+ content = readFileSync19(skillMdPath, "utf-8");
56129
56355
  } catch {
56130
56356
  continue;
56131
56357
  }
@@ -56162,7 +56388,7 @@ function findExtensionSkillPath(name) {
56162
56388
  continue;
56163
56389
  let content;
56164
56390
  try {
56165
- content = readFileSync18(skillMdPath, "utf-8");
56391
+ content = readFileSync19(skillMdPath, "utf-8");
56166
56392
  } catch {
56167
56393
  continue;
56168
56394
  }
@@ -57874,7 +58100,7 @@ var require_cli_spinners = __commonJS((exports, module) => {
57874
58100
  });
57875
58101
 
57876
58102
  // src/lib/auth-store.ts
57877
- import { chmodSync as chmodSync2, existsSync as existsSync20, mkdirSync as mkdirSync11, readFileSync as readFileSync19, renameSync as renameSync7, statSync as statSync11, unlinkSync as unlinkSync5, writeFileSync as writeFileSync10 } from "fs";
58103
+ import { chmodSync as chmodSync2, existsSync as existsSync20, mkdirSync as mkdirSync11, readFileSync as readFileSync20, renameSync as renameSync7, statSync as statSync11, unlinkSync as unlinkSync5, writeFileSync as writeFileSync10 } from "fs";
57878
58104
  import { basename as basename11, dirname as dirname19, join as join35 } from "path";
57879
58105
  function getAuthFilePath(env3 = process.env) {
57880
58106
  return skillsCredentialFilePath(env3);
@@ -57888,7 +58114,7 @@ function getAuthIdentity(env3 = process.env) {
57888
58114
  }
57889
58115
  function readIdentity(env3 = process.env) {
57890
58116
  try {
57891
- const parsed = JSON.parse(readFileSync19(getIdentityFilePath(env3), "utf-8"));
58117
+ const parsed = JSON.parse(readFileSync20(getIdentityFilePath(env3), "utf-8"));
57892
58118
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
57893
58119
  return {};
57894
58120
  const record2 = parsed;
@@ -57919,7 +58145,7 @@ function writeCredentialValues(values2, env3 = process.env) {
57919
58145
  const lines = [];
57920
58146
  const written = new Set;
57921
58147
  if (existsSync20(file)) {
57922
- for (const raw of readFileSync19(file, "utf-8").split(/\r?\n/)) {
58148
+ for (const raw of readFileSync20(file, "utf-8").split(/\r?\n/)) {
57923
58149
  const match = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/.exec(raw);
57924
58150
  const key = match?.[1];
57925
58151
  if (key && key in values2) {
@@ -57957,7 +58183,7 @@ function readCredentialValue(key, env3 = process.env) {
57957
58183
  if (!existsSync20(file))
57958
58184
  return null;
57959
58185
  try {
57960
- for (const raw of readFileSync19(file, "utf-8").split(/\r?\n/)) {
58186
+ for (const raw of readFileSync20(file, "utf-8").split(/\r?\n/)) {
57961
58187
  const match = new RegExp(`^\\s*(?:export\\s+)?${key}\\s*=\\s*(.*)$`).exec(raw);
57962
58188
  if (!match)
57963
58189
  continue;
@@ -57975,7 +58201,7 @@ function readCredentialValue(key, env3 = process.env) {
57975
58201
  }
57976
58202
  function readIdentityRecord(env3 = process.env) {
57977
58203
  try {
57978
- const parsed = JSON.parse(readFileSync19(getIdentityFilePath(env3), "utf-8"));
58204
+ const parsed = JSON.parse(readFileSync20(getIdentityFilePath(env3), "utf-8"));
57979
58205
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
57980
58206
  } catch {
57981
58207
  return null;
@@ -60264,7 +60490,7 @@ __export(exports_regexes, {
60264
60490
  idnEmail: () => idnEmail,
60265
60491
  httpProtocol: () => httpProtocol,
60266
60492
  html5Email: () => html5Email,
60267
- hostname: () => hostname,
60493
+ hostname: () => hostname2,
60268
60494
  hex: () => hex,
60269
60495
  guid: () => guid,
60270
60496
  extendedDuration: () => extendedDuration,
@@ -60324,7 +60550,7 @@ var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, extendedDuration, guid, uui
60324
60550
  }, uuid42, uuid6, uuid7, email2, html5Email, rfc5322Email, unicodeEmail, idnEmail, browserEmail, _emoji = `^[\\p{Extended_Pictographic}\\p{Emoji_Component}]+$`, ipv4, ipv6, mac = (delimiter) => {
60325
60551
  const escapedDelim = escapeRegex(delimiter ?? ":");
60326
60552
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
60327
- }, cidrv4, cidrv6, base64, base64url, hostname, domain, httpProtocol, e164, creditCard, dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`, date2, string = (params) => {
60553
+ }, cidrv4, cidrv6, base64, base64url, hostname2, domain, httpProtocol, e164, creditCard, dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`, date2, string = (params) => {
60328
60554
  const regex2 = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
60329
60555
  return new RegExp(`^${regex2}$`);
60330
60556
  }, bigint, integer, number, boolean, _null, _undefined, lowercase, uppercase, hex, md5_hex, md5_base64, md5_base64url, sha1_hex, sha1_base64, sha1_base64url, sha256_hex, sha256_base64, sha256_base64url, sha384_hex, sha384_base64, sha384_base64url, sha512_hex, sha512_base64, sha512_base64url;
@@ -60354,7 +60580,7 @@ var init_regexes = __esm(() => {
60354
60580
  cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
60355
60581
  base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;
60356
60582
  base64url = /^[A-Za-z0-9_-]*$/;
60357
- hostname = /^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;
60583
+ hostname2 = /^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;
60358
60584
  domain = /^(?=.{1,253}$)([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,63}$/;
60359
60585
  httpProtocol = /^https?$/;
60360
60586
  e164 = /^\+[1-9]\d{6,14}$/;
@@ -61006,9 +61232,9 @@ function parseURLObject(trimmed, def) {
61006
61232
  function stripTabAndNewline(value) {
61007
61233
  return value.replace(asciiTabOrNewline, "");
61008
61234
  }
61009
- function urlHostnameOk(url, hostname2) {
61010
- hostname2.lastIndex = 0;
61011
- return hostname2.test(url.hostname);
61235
+ function urlHostnameOk(url, hostname3) {
61236
+ hostname3.lastIndex = 0;
61237
+ return hostname3.test(url.hostname);
61012
61238
  }
61013
61239
  function urlProtocolOk(url, protocol) {
61014
61240
  protocol.lastIndex = 0;
@@ -75310,7 +75536,7 @@ __export(exports_schemas2, {
75310
75536
  int: () => int,
75311
75537
  instanceof: () => _instanceof,
75312
75538
  httpUrl: () => httpUrl,
75313
- hostname: () => hostname2,
75539
+ hostname: () => hostname3,
75314
75540
  hex: () => hex2,
75315
75541
  hash: () => hash4,
75316
75542
  guid: () => guid2,
@@ -75512,7 +75738,7 @@ function jwt(params) {
75512
75738
  function stringFormat(format, fnOrRegex, _params = {}) {
75513
75739
  return _stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params);
75514
75740
  }
75515
- function hostname2(_params) {
75741
+ function hostname3(_params) {
75516
75742
  return _stringFormat(ZodCustomStringFormat, "hostname", exports_regexes.hostname, _params);
75517
75743
  }
75518
75744
  function hex2(_params) {
@@ -77776,7 +78002,7 @@ __export(exports_external, {
77776
78002
  input: () => input,
77777
78003
  includes: () => _includes,
77778
78004
  httpUrl: () => httpUrl,
77779
- hostname: () => hostname2,
78005
+ hostname: () => hostname3,
77780
78006
  hex: () => hex2,
77781
78007
  hash: () => hash4,
77782
78008
  guid: () => guid2,
@@ -79904,7 +80130,7 @@ var init_remote_auth = __esm(() => {
79904
80130
 
79905
80131
  // src/lib/sign-in.ts
79906
80132
  import { createHash as createHash19 } from "crypto";
79907
- import { chmodSync as chmodSync3, mkdirSync as mkdirSync12, readFileSync as readFileSync20, readdirSync as readdirSync13, renameSync as renameSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync11 } from "fs";
80133
+ import { chmodSync as chmodSync3, mkdirSync as mkdirSync12, readFileSync as readFileSync21, readdirSync as readdirSync13, renameSync as renameSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync11 } from "fs";
79908
80134
  import { basename as basename12, dirname as dirname20, join as join36 } from "path";
79909
80135
  function isRecord6(value) {
79910
80136
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -80080,7 +80306,7 @@ function loadPendingDeviceSignIn(origin, env3 = process.env, now3 = Date.now())
80080
80306
  let parsed;
80081
80307
  try {
80082
80308
  path = pendingDeviceSignInPath(origin, env3);
80083
- parsed = JSON.parse(readFileSync20(path, "utf8"));
80309
+ parsed = JSON.parse(readFileSync21(path, "utf8"));
80084
80310
  } catch {
80085
80311
  return null;
80086
80312
  }
@@ -80125,7 +80351,7 @@ function pendingDeviceSignInOrigins(env3 = process.env, now3 = Date.now()) {
80125
80351
  if (!entry.startsWith(`${location.stem}-`) || !/-[0-9a-f]{16}\.json$/.test(entry))
80126
80352
  continue;
80127
80353
  try {
80128
- const parsed = JSON.parse(readFileSync20(join36(location.dir, entry), "utf8"));
80354
+ const parsed = JSON.parse(readFileSync21(join36(location.dir, entry), "utf8"));
80129
80355
  if (isRecord6(parsed) && typeof parsed.origin === "string" && Number(parsed.expiresAt) > now3 && pendingDeviceSignInPath(parsed.origin, env3) === join36(location.dir, entry))
80130
80356
  origins.push(parsed.origin);
80131
80357
  } catch {}
@@ -80211,9 +80437,12 @@ async function revokeStoredKey(origin, apiKey) {
80211
80437
  return { outcome: "revoked" };
80212
80438
  return { outcome: "not_revoked", detail: "the server answered without confirming revocation" };
80213
80439
  }
80214
- function activeCredentialSource(env3, options) {
80440
+ function activeCredentialSource(env3, options, profile) {
80215
80441
  try {
80216
- return resolveCredential("skills", env3, options.credentials)?.source ?? null;
80442
+ return resolveCredential("skills", env3, {
80443
+ ...options.credentials,
80444
+ profile: profile ?? options.credentials?.profile ?? selectedSkillsProfile(env3) ?? undefined
80445
+ })?.source ?? null;
80217
80446
  } catch {
80218
80447
  return null;
80219
80448
  }
@@ -80290,7 +80519,7 @@ async function signOut(options = {}) {
80290
80519
  const selected = selectedSkillsProfile(env3);
80291
80520
  const other = options.environmentProfile;
80292
80521
  if (other !== undefined && other !== selected) {
80293
- const otherSource = activeCredentialSource({ ...env3, HASNA_PROFILE: other }, fleet);
80522
+ const otherSource = activeCredentialSource({ ...env3, HASNA_PROFILE: other }, fleet, other);
80294
80523
  if (otherSource) {
80295
80524
  reasons.push({
80296
80525
  code: "credential_still_active",
@@ -80299,7 +80528,7 @@ async function signOut(options = {}) {
80299
80528
  }
80300
80529
  }
80301
80530
  if (selected && !still) {
80302
- notes.push(`HASNA_PROFILE still selects profile "${selected}", which now has no credential. The next command will stop and name it until you run skills login or unset HASNA_PROFILE.`);
80531
+ notes.push(selectedCliSkillsCredentialProfile() ? `--profile selected profile "${selected}", which now has no credential. A future command with the same flag will stop and name it until you run skills login for that profile.` : `HASNA_PROFILE still selects profile "${selected}", which now has no credential. The next command will stop and name it until you run skills login or unset HASNA_PROFILE.`);
80303
80532
  }
80304
80533
  if (!stored && reasons.length === 0)
80305
80534
  notes.push("Already signed out: this profile has no credential stored by skills login.");
@@ -80796,7 +81025,7 @@ var init_skill_bundles = __esm(() => {
80796
81025
  });
80797
81026
 
80798
81027
  // src/lib/pull.ts
80799
- import { existsSync as existsSync21, mkdirSync as mkdirSync13, mkdtempSync as mkdtempSync3, readFileSync as readFileSync21, renameSync as renameSync9, rmSync as rmSync6, writeFileSync as writeFileSync12 } from "fs";
81028
+ import { existsSync as existsSync21, mkdirSync as mkdirSync13, mkdtempSync as mkdtempSync3, readFileSync as readFileSync23, renameSync as renameSync9, rmSync as rmSync6, writeFileSync as writeFileSync12 } from "fs";
80800
81029
  import { dirname as dirname21, join as join37 } from "path";
80801
81030
  async function pullSkills(options = {}) {
80802
81031
  const client2 = options.client !== undefined ? options.client : await createRemoteSkillsClient();
@@ -80958,7 +81187,7 @@ function reconcileTombstone(slug2, corpusOptions) {
80958
81187
  }
80959
81188
  function readPullMarker(dir) {
80960
81189
  try {
80961
- return JSON.parse(readFileSync21(join37(dir, PULL_MARKER_FILE), "utf-8"));
81190
+ return JSON.parse(readFileSync23(join37(dir, PULL_MARKER_FILE), "utf-8"));
80962
81191
  } catch {
80963
81192
  return null;
80964
81193
  }
@@ -81460,6 +81689,24 @@ Receipt SHA256: ${result2.receiptSha256}`);
81460
81689
  reportContextError(error61, options.json);
81461
81690
  }
81462
81691
  });
81692
+ sessions.command("recover-lock <id>").option("--apply", "Archive the exact reviewed stale lock", false).option("--review-digest <sha256>", "Exact digest returned by the lock review; required with --apply").option("--confirm-local-host", "Confirm this PID-only legacy lock was created on this host", false).option("--json", "Return lock metadata or recovery result as JSON", false).description("Review a stale session write lock, then archive it without changing the receipt").action(async (id, options) => {
81693
+ try {
81694
+ if (!options.apply) {
81695
+ const result2 = inspectSessionWriteLock(id);
81696
+ await writeCliOutput(options.json ? JSON.stringify(result2) : `Lock for ${JSON.stringify(id)}: PID ${result2.pid}, schema ${result2.schemaVersion}, modified ${result2.lockMtime}.
81697
+ Receipt SHA256: ${result2.receiptSha256}
81698
+ Review digest: ${result2.reviewDigest}`);
81699
+ return;
81700
+ }
81701
+ if (!options.reviewDigest || !/^[a-f0-9]{64}$/.test(options.reviewDigest) || !options.confirmLocalHost) {
81702
+ throw new SkillSelectionError("SESSION_LOCK_REVIEW_REQUIRED", "Apply requires the exact review digest and --confirm-local-host after verifying this lock belongs to this host.");
81703
+ }
81704
+ const archivePath = recoverSessionWriteLock(id, options.reviewDigest);
81705
+ await writeCliOutput(options.json ? JSON.stringify({ sessionId: id, recovered: true, archivePath }) : `Archived the stale lock at ${archivePath}. The session receipt was not changed.`);
81706
+ } catch (error61) {
81707
+ reportContextError(error61, options.json);
81708
+ }
81709
+ });
81463
81710
  sessions.command("reconcile <id>").requiredOption("--from-profile <id>", "Expected current session profile").requiredOption("--from-revision <revision>", "Expected current session profile revision").requiredOption("--receipt-sha256 <sha256>", "Expected exact current receipt bytes").requiredOption("--selection-profile <id>", "Intended target selection profile").requiredOption("--profile-revision <revision>", "Expected current API target revision").option("--apply", "Archive the old receipt and atomically apply the reviewed plan", false).option("--plan-digest <sha256>", "Exact reviewed plan digest; required with --apply").option("--plan-issued-at <timestamp>", "Exact reviewed plan issuedAt; required with --apply").option("--plan-expires-at <timestamp>", "Exact reviewed plan expiresAt; required with --apply").option("--json", "Return the plan or application receipt as JSON", false).description("Plan an intentional migration of one session pin; ordinary hooks never migrate pins").action(async (id, options) => {
81464
81711
  try {
81465
81712
  const result2 = await reconcileSkillSession({ ...options, sessionId: id });
@@ -81577,13 +81824,13 @@ var init_context = __esm(() => {
81577
81824
  });
81578
81825
 
81579
81826
  // src/cli/commands/profile-sync.ts
81580
- import { hostname as hostname3 } from "os";
81827
+ import { hostname as hostname4 } from "os";
81581
81828
  async function handleProfileSync(options, dependencies = {}) {
81582
81829
  try {
81583
81830
  const result2 = await syncSelectionProfile(selectedProfileId(options.selectionProfile ?? options.profile), {
81584
81831
  ...dependencies,
81585
81832
  projectDir: options.project ? process.cwd() : dependencies.projectDir,
81586
- stationId: options.stationReport === false ? undefined : options.station ?? dependencies.stationId ?? process.env.HASNA_STATION ?? hostname3(),
81833
+ stationId: options.stationReport === false ? undefined : options.station ?? dependencies.stationId ?? process.env.HASNA_STATION ?? hostname4(),
81587
81834
  check: options.check ?? dependencies.check
81588
81835
  });
81589
81836
  if (options.json)
@@ -82311,7 +82558,7 @@ var exports_introspect = {};
82311
82558
  __export(exports_introspect, {
82312
82559
  registerIntrospect: () => registerIntrospect
82313
82560
  });
82314
- import { existsSync as existsSync22, readFileSync as readFileSync23 } from "fs";
82561
+ import { existsSync as existsSync22, readFileSync as readFileSync25 } from "fs";
82315
82562
  import { join as join38 } from "path";
82316
82563
  import { execSync } from "child_process";
82317
82564
  function registerIntrospect(parent) {
@@ -82533,7 +82780,7 @@ function handleDiff(name, options) {
82533
82780
  present: existsSync22(canonicalSkillMd),
82534
82781
  path: canonicalDir,
82535
82782
  ...existsSync22(canonicalSkillMd) ? { hash: hashSkillMarkdownFile(canonicalSkillMd) } : {},
82536
- ...existsSync22(canonicalSkillMd) ? { stub: isPointerSkillMd(readFileSync23(canonicalSkillMd, "utf-8")) } : {}
82783
+ ...existsSync22(canonicalSkillMd) ? { stub: isPointerSkillMd(readFileSync25(canonicalSkillMd, "utf-8")) } : {}
82537
82784
  };
82538
82785
  const pinned = getInstalledSkills().includes(bare);
82539
82786
  const installMeta = getInstallMeta();
@@ -82542,7 +82789,7 @@ function handleDiff(name, options) {
82542
82789
  let registryVersion = "unknown";
82543
82790
  if (existsSync22(registryPkgPath)) {
82544
82791
  try {
82545
- registryVersion = JSON.parse(readFileSync23(registryPkgPath, "utf-8")).version || "unknown";
82792
+ registryVersion = JSON.parse(readFileSync25(registryPkgPath, "utf-8")).version || "unknown";
82546
82793
  } catch {}
82547
82794
  }
82548
82795
  const upToDate = installedVersion === registryVersion;
@@ -82556,7 +82803,7 @@ function handleDiff(name, options) {
82556
82803
  let stub;
82557
82804
  if (present && existsSync22(skillMdPath)) {
82558
82805
  try {
82559
- stub = isPointerSkillMd(readFileSync23(skillMdPath, "utf-8"));
82806
+ stub = isPointerSkillMd(readFileSync25(skillMdPath, "utf-8"));
82560
82807
  } catch {
82561
82808
  stub = undefined;
82562
82809
  }
@@ -83094,7 +83341,7 @@ var exports_init = {};
83094
83341
  __export(exports_init, {
83095
83342
  registerSetup: () => registerSetup
83096
83343
  });
83097
- import { existsSync as existsSync23, readFileSync as readFileSync25, writeFileSync as writeFileSync13, appendFileSync } from "fs";
83344
+ import { existsSync as existsSync23, readFileSync as readFileSync26, writeFileSync as writeFileSync13, appendFileSync } from "fs";
83098
83345
  import { join as join39 } from "path";
83099
83346
  function registerSetup(parent) {
83100
83347
  parent.command("init").option("--json", "Output as JSON", false).option("--for <agent>", "Detect project type and show MCP registration guidance for agent").option("--scope <scope>", "Deprecated; agent skill-folder installs are disabled", "global").description("Initialize project for pinned skills (.env.example, .gitignore)").action((options) => handleInit(options));
@@ -83189,7 +83436,7 @@ Use: skills render`));
83189
83436
  console.log(source_default.dim(" No environment variables detected across pinned skills"));
83190
83437
  const gitignorePath = join39(cwd2, ".gitignore");
83191
83438
  const gitignoreEntries = [".skills/runs/", ".skills/exports/", ".skills/tmp/"];
83192
- let gitignoreContent = existsSync23(gitignorePath) ? readFileSync25(gitignorePath, "utf-8") : "";
83439
+ let gitignoreContent = existsSync23(gitignorePath) ? readFileSync26(gitignorePath, "utf-8") : "";
83193
83440
  let gitignoreUpdated = false;
83194
83441
  const missingEntries = gitignoreEntries.filter((entry) => !gitignoreContent.includes(entry));
83195
83442
  if (missingEntries.length > 0) {
@@ -83244,7 +83491,7 @@ async function handleImport(file2, options) {
83244
83491
  process.exitCode = 1;
83245
83492
  return;
83246
83493
  }
83247
- raw = readFileSync25(file2, "utf-8");
83494
+ raw = readFileSync26(file2, "utf-8");
83248
83495
  }
83249
83496
  } catch (err) {
83250
83497
  const error61 = `Failed to read file: ${err.message}`;
@@ -83341,7 +83588,7 @@ var init_init = __esm(() => {
83341
83588
  });
83342
83589
 
83343
83590
  // src/lib/home-adoption.ts
83344
- import { constants as constants13, closeSync as closeSync15, fstatSync as fstatSync15, lstatSync as lstatSync22, openSync as openSync15, readSync as readSync12, existsSync as existsSync24, mkdirSync as mkdirSync14, readdirSync as readdirSync14, readFileSync as readFileSync26, rmSync as rmSync7, statSync as statSync12, writeFileSync as writeFileSync14 } from "fs";
83591
+ import { constants as constants13, closeSync as closeSync15, fstatSync as fstatSync15, lstatSync as lstatSync22, openSync as openSync15, readSync as readSync12, existsSync as existsSync24, mkdirSync as mkdirSync14, readdirSync as readdirSync14, readFileSync as readFileSync27, rmSync as rmSync7, statSync as statSync12, writeFileSync as writeFileSync14 } from "fs";
83345
83592
  import { homedir as homedir8 } from "os";
83346
83593
  import { join as join40 } from "path";
83347
83594
  function indexCanonicalCorpus(corpusRoot) {
@@ -83445,7 +83692,7 @@ function appendConflictsLedger(appDir, conflicts) {
83445
83692
  let ledger = { version: 1, entries: [] };
83446
83693
  if (existsSync24(ledgerPath)) {
83447
83694
  try {
83448
- const parsed = JSON.parse(readFileSync26(ledgerPath, "utf-8"));
83695
+ const parsed = JSON.parse(readFileSync27(ledgerPath, "utf-8"));
83449
83696
  if (parsed && typeof parsed === "object" && Array.isArray(parsed.entries)) {
83450
83697
  ledger = parsed;
83451
83698
  }
@@ -83594,7 +83841,7 @@ var init_home_adoption = __esm(() => {
83594
83841
  });
83595
83842
 
83596
83843
  // src/lib/home-census.ts
83597
- import { existsSync as existsSync25, readFileSync as readFileSync27, readdirSync as readdirSync15, statSync as statSync13 } from "fs";
83844
+ import { existsSync as existsSync25, readFileSync as readFileSync28, readdirSync as readdirSync15, statSync as statSync13 } from "fs";
83598
83845
  import { homedir as homedir9 } from "os";
83599
83846
  import { join as join41 } from "path";
83600
83847
  function sortEntries(entries) {
@@ -83665,14 +83912,14 @@ function censusHomeDrift(options = {}) {
83665
83912
  if (homeHash !== canonicalHash) {
83666
83913
  let homeStub;
83667
83914
  try {
83668
- homeStub = isPointerSkillMd(readFileSync27(skillMdPath, "utf-8"));
83915
+ homeStub = isPointerSkillMd(readFileSync28(skillMdPath, "utf-8"));
83669
83916
  } catch {
83670
83917
  homeStub = undefined;
83671
83918
  }
83672
83919
  let canonicalStub;
83673
83920
  const canonicalSkillMd = join41(corpusRoot, skill, "SKILL.md");
83674
83921
  try {
83675
- canonicalStub = isPointerSkillMd(readFileSync27(canonicalSkillMd, "utf-8"));
83922
+ canonicalStub = isPointerSkillMd(readFileSync28(canonicalSkillMd, "utf-8"));
83676
83923
  } catch {
83677
83924
  canonicalStub = undefined;
83678
83925
  }
@@ -83710,7 +83957,7 @@ var init_home_census = __esm(() => {
83710
83957
  });
83711
83958
 
83712
83959
  // src/cli/env-assignment.ts
83713
- import { closeSync as closeSync16, constants as constants14, fstatSync as fstatSync16, ftruncateSync as ftruncateSync2, lstatSync as lstatSync23, openSync as openSync16, readFileSync as readFileSync28, writeSync as writeSync3 } from "fs";
83960
+ import { closeSync as closeSync16, constants as constants14, fstatSync as fstatSync16, ftruncateSync as ftruncateSync2, lstatSync as lstatSync23, openSync as openSync16, readFileSync as readFileSync29, writeSync as writeSync3 } from "fs";
83714
83961
  function serializeValue(value) {
83715
83962
  if (controls.test(value))
83716
83963
  throw new EnvAssignmentError("Environment values cannot contain control characters or newlines.");
@@ -83805,7 +84052,7 @@ function setEnvAssignment(path, assignment) {
83805
84052
  }
83806
84053
  let prepared = initial2;
83807
84054
  if (previous) {
83808
- const original = readFileSync28(descriptor), text4 = original.toString("utf8");
84055
+ const original = readFileSync29(descriptor), text4 = original.toString("utf8");
83809
84056
  if (!Buffer.from(text4, "utf8").equals(original))
83810
84057
  throw new EnvAssignmentError(INVALID_LAYOUT);
83811
84058
  prepared = prepareEnvAssignment(assignment, text4);
@@ -83892,7 +84139,7 @@ var exports_diagnostic = {};
83892
84139
  __export(exports_diagnostic, {
83893
84140
  registerDiagnostic: () => registerDiagnostic
83894
84141
  });
83895
- import { existsSync as existsSync26, readFileSync as readFileSync29, readdirSync as readdirSync16, statSync as statSync14 } from "fs";
84142
+ import { existsSync as existsSync26, readFileSync as readFileSync30, readdirSync as readdirSync16, statSync as statSync14 } from "fs";
83896
84143
  import { join as join42 } from "path";
83897
84144
  import { execSync as execSync2 } from "child_process";
83898
84145
  function registerDiagnostic(parent) {
@@ -84133,7 +84380,7 @@ function handleOutdated(options) {
84133
84380
  let registryVersion = "unknown";
84134
84381
  if (existsSync26(registryPkgPath))
84135
84382
  try {
84136
- registryVersion = JSON.parse(readFileSync29(registryPkgPath, "utf-8")).version || "unknown";
84383
+ registryVersion = JSON.parse(readFileSync30(registryPkgPath, "utf-8")).version || "unknown";
84137
84384
  } catch {}
84138
84385
  if (installedVersion !== registryVersion)
84139
84386
  pins.push({ skill: name, installedVersion, registryVersion });
@@ -84343,8 +84590,8 @@ var init_cloud_executions = __esm(() => {
84343
84590
 
84344
84591
  // node_modules/@hasna/secrets/dist/sdk.js
84345
84592
  import { isIP as isIP3 } from "net";
84346
- import { spawnSync as spawnSync2 } from "child_process";
84347
- import { closeSync as closeSync17, fstatSync as fstatSync17, openSync as openSync17, readFileSync as readFileSync30 } from "fs";
84593
+ import { spawnSync as spawnSync3 } from "child_process";
84594
+ import { closeSync as closeSync17, fstatSync as fstatSync17, openSync as openSync17, readFileSync as readFileSync31 } from "fs";
84348
84595
  import { O_NOFOLLOW as O_NOFOLLOW3, O_NONBLOCK as O_NONBLOCK3, O_RDONLY as O_RDONLY3 } from "constants";
84349
84596
  import { createRequire as createRequire2 } from "module";
84350
84597
  import { hostname as osHostname2 } from "os";
@@ -84470,7 +84717,7 @@ function readAppConfigFile2(path) {
84470
84717
  unsafe("the file is not owned by the current user");
84471
84718
  if (before2.size > MAX_CREDENTIAL_FILE_BYTES2)
84472
84719
  unsafe("the file exceeds the size limit");
84473
- const bytes = readFileSync30(fd);
84720
+ const bytes = readFileSync31(fd);
84474
84721
  const after2 = fstatSync17(fd);
84475
84722
  if (!configFileReadsCoherent2(before2, after2)) {
84476
84723
  unsafe("the file changed while being read");
@@ -84618,7 +84865,7 @@ function isAmbientEnvironment2(env3) {
84618
84865
  return env3 === process.env || env3[AMBIENT_ENVIRONMENT2] === true;
84619
84866
  }
84620
84867
  function defaultKeychainRunner2(argv) {
84621
- const result2 = spawnSync2(KEYCHAIN_SECURITY_BIN2, [...argv], {
84868
+ const result2 = spawnSync3(KEYCHAIN_SECURITY_BIN2, [...argv], {
84622
84869
  encoding: "utf8",
84623
84870
  stdio: ["ignore", "pipe", "pipe"],
84624
84871
  timeout: KEYCHAIN_SPAWN_TIMEOUT_MS2
@@ -90337,7 +90584,7 @@ var init_runs = __esm(() => {
90337
90584
 
90338
90585
  // src/lib/run-state.ts
90339
90586
  import { createHash as createHash24, randomBytes } from "crypto";
90340
- import { existsSync as existsSync27, mkdirSync as mkdirSync16, readFileSync as readFileSync31, readdirSync as readdirSync17, statSync as statSync15, writeFileSync as writeFileSync16 } from "fs";
90587
+ import { existsSync as existsSync27, mkdirSync as mkdirSync16, readFileSync as readFileSync32, readdirSync as readdirSync17, statSync as statSync15, writeFileSync as writeFileSync16 } from "fs";
90341
90588
  import { extname, join as join45, relative as relative6 } from "path";
90342
90589
  function createSkillRun(params, targetDir = process.cwd()) {
90343
90590
  const now3 = new Date;
@@ -90409,7 +90656,7 @@ function appendRunEvent(context, event, data = {}) {
90409
90656
  const line = JSON.stringify({ ts: new Date().toISOString(), event, ...data }) + `
90410
90657
  `;
90411
90658
  const path = join45(context.runDir, "events.ndjson");
90412
- const previous = existsSync27(path) ? readFileSync31(path, "utf-8") : "";
90659
+ const previous = existsSync27(path) ? readFileSync32(path, "utf-8") : "";
90413
90660
  writeFileSync16(path, previous + line);
90414
90661
  }
90415
90662
  function listSkillRuns(targetDir = process.cwd(), limit = 50) {
@@ -90469,7 +90716,7 @@ function collectRunArtifacts(context) {
90469
90716
  const artifacts = [];
90470
90717
  for (const path of walkFiles(context.exportDir)) {
90471
90718
  const stat2 = statSync15(path);
90472
- const bytes = readFileSync31(path);
90719
+ const bytes = readFileSync32(path);
90473
90720
  artifacts.push({
90474
90721
  path: toProjectRelative(context.targetDir, path),
90475
90722
  mime: mimeForPath(path),
@@ -90484,7 +90731,7 @@ function readRunRecord(runDir) {
90484
90731
  if (!existsSync27(path))
90485
90732
  return null;
90486
90733
  try {
90487
- return JSON.parse(readFileSync31(path, "utf-8"));
90734
+ return JSON.parse(readFileSync32(path, "utf-8"));
90488
90735
  } catch {
90489
90736
  return null;
90490
90737
  }
@@ -102509,7 +102756,7 @@ var init_remote_customer_operations = __esm(() => {
102509
102756
  });
102510
102757
 
102511
102758
  // src/lib/workspace-profile.ts
102512
- import { constants as constants16, closeSync as closeSync19, fstatSync as fstatSync19, lstatSync as lstatSync24, mkdirSync as mkdirSync17, mkdtempSync as mkdtempSync5, openSync as openSync19, readFileSync as readFileSync32, renameSync as renameSync10, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "fs";
102759
+ import { constants as constants16, closeSync as closeSync19, fstatSync as fstatSync19, lstatSync as lstatSync24, mkdirSync as mkdirSync17, mkdtempSync as mkdtempSync5, openSync as openSync19, readFileSync as readFileSync33, renameSync as renameSync10, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "fs";
102513
102760
  import { dirname as dirname23, join as join46 } from "path";
102514
102761
  function stat2(path) {
102515
102762
  try {
@@ -102528,7 +102775,7 @@ function safeText(file2) {
102528
102775
  const s = fstatSync19(fd);
102529
102776
  if (!s.isFile() || s.size > 65536 || ![256, 384].includes(s.mode & 4095) || process.getuid && s.uid !== process.getuid())
102530
102777
  return fail3("The selected profile must use bounded owner-only regular files.");
102531
- return readFileSync32(fd, "utf8");
102778
+ return readFileSync33(fd, "utf8");
102532
102779
  } finally {
102533
102780
  closeSync19(fd);
102534
102781
  }
@@ -105406,7 +105653,7 @@ var init_resource_meta_tools = __esm(() => {
105406
105653
  });
105407
105654
 
105408
105655
  // src/lib/scheduler.ts
105409
- import { existsSync as existsSync30, readFileSync as readFileSync33, writeFileSync as writeFileSync19, mkdirSync as mkdirSync20 } from "fs";
105656
+ import { existsSync as existsSync30, readFileSync as readFileSync34, writeFileSync as writeFileSync19, mkdirSync as mkdirSync20 } from "fs";
105410
105657
  import { join as join50 } from "path";
105411
105658
  function getSchedulesPath(targetDir = process.cwd()) {
105412
105659
  return join50(targetDir, ".skills", "schedules.json");
@@ -105415,7 +105662,7 @@ function loadSchedules(targetDir = process.cwd()) {
105415
105662
  const path = getSchedulesPath(targetDir);
105416
105663
  if (existsSync30(path)) {
105417
105664
  try {
105418
- return JSON.parse(readFileSync33(path, "utf-8"));
105665
+ return JSON.parse(readFileSync34(path, "utf-8"));
105419
105666
  } catch {}
105420
105667
  }
105421
105668
  return { version: 1, schedules: [] };
@@ -105725,7 +105972,7 @@ import { createHash as createHash25, createHmac as createHmac3 } from "crypto";
105725
105972
  import {
105726
105973
  existsSync as existsSync31,
105727
105974
  mkdirSync as mkdirSync21,
105728
- readFileSync as readFileSync34,
105975
+ readFileSync as readFileSync35,
105729
105976
  readdirSync as readdirSync19,
105730
105977
  statSync as statSync17,
105731
105978
  writeFileSync as writeFileSync20
@@ -105793,7 +106040,7 @@ function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
105793
106040
  const files = [];
105794
106041
  if (existsSync31(projectStateDir)) {
105795
106042
  for (const filePath of walkFiles2(projectStateDir)) {
105796
- const bytes = readFileSync34(filePath);
106043
+ const bytes = readFileSync35(filePath);
105797
106044
  const relativePath = toPosix(relative7(targetDir, filePath));
105798
106045
  files.push({
105799
106046
  path: relativePath,
@@ -106698,7 +106945,7 @@ var exports_runtime_mcp = {};
106698
106945
  __export(exports_runtime_mcp, {
106699
106946
  handleMcp: () => handleMcp
106700
106947
  });
106701
- import { existsSync as existsSync32, mkdirSync as mkdirSync23, readFileSync as readFileSync35, writeFileSync as writeFileSync22 } from "fs";
106948
+ import { existsSync as existsSync32, mkdirSync as mkdirSync23, readFileSync as readFileSync36, writeFileSync as writeFileSync22 } from "fs";
106702
106949
  import { homedir as homedir10 } from "os";
106703
106950
  import { dirname as dirname28, join as join53 } from "path";
106704
106951
  async function handleMcp(options) {
@@ -106809,7 +107056,7 @@ function registerCodexMcp(command) {
106809
107056
  const config2 = `[mcp_servers.${MCP_SERVER_NAME}]
106810
107057
  command = ${JSON.stringify(command)}`;
106811
107058
  try {
106812
- const current = existsSync32(path) ? readFileSync35(path, "utf-8") : "";
107059
+ const current = existsSync32(path) ? readFileSync36(path, "utf-8") : "";
106813
107060
  writeTextFile(path, upsertTomlSection(current, `[mcp_servers.${MCP_SERVER_NAME}]`, `command = ${JSON.stringify(command)}`));
106814
107061
  return { agent: "codex", success: true, path, config: config2 };
106815
107062
  } catch (err) {
@@ -106861,7 +107108,7 @@ function registerJsonMcpServer(agent, path, containerKey, server2) {
106861
107108
  function readJsonObject2(path) {
106862
107109
  if (!existsSync32(path))
106863
107110
  return {};
106864
- const raw = readFileSync35(path, "utf-8").trim();
107111
+ const raw = readFileSync36(path, "utf-8").trim();
106865
107112
  if (!raw)
106866
107113
  return {};
106867
107114
  const parsed = JSON.parse(raw);
@@ -106985,7 +107232,7 @@ __export(exports_runtime, {
106985
107232
  registerRuntime: () => registerRuntime
106986
107233
  });
106987
107234
  import { createHash as createHash26, randomUUID as randomUUID9 } from "crypto";
106988
- import { lstatSync as lstatSync27, mkdirSync as mkdirSync24, readFileSync as readFileSync36, realpathSync as realpathSync11, writeFileSync as writeFileSync23 } from "fs";
107235
+ import { lstatSync as lstatSync27, mkdirSync as mkdirSync24, readFileSync as readFileSync37, realpathSync as realpathSync11, writeFileSync as writeFileSync23 } from "fs";
106989
107236
  import { basename as basename13, isAbsolute as isAbsolute22, join as join54 } from "path";
106990
107237
  import { createInterface } from "readline";
106991
107238
  function registerRuntime(parent) {
@@ -107438,7 +107685,7 @@ async function handleRun(name, args2, options, separatorBeforeSkill) {
107438
107685
  const info = lstatSync27(path);
107439
107686
  if (!info.isFile() || info.size > 20 * 1024 * 1024)
107440
107687
  throw new Error("Input must be a regular file no larger than 20 MiB");
107441
- return { name: basename13(path), bytes: new Uint8Array(readFileSync36(path)) };
107688
+ return { name: basename13(path), bytes: new Uint8Array(readFileSync37(path)) };
107442
107689
  });
107443
107690
  describeRemoteFiles(inputFiles);
107444
107691
  client2 = new RemoteSkillsClient(routing.apiKey, routing.apiOrigin);
@@ -108610,7 +108857,7 @@ import { createHash as createHash27 } from "crypto";
108610
108857
  import {
108611
108858
  copyFileSync,
108612
108859
  mkdirSync as mkdirSync25,
108613
- readFileSync as readFileSync37,
108860
+ readFileSync as readFileSync38,
108614
108861
  statSync as statSync19,
108615
108862
  writeFileSync as writeFileSync24
108616
108863
  } from "fs";
@@ -108621,7 +108868,7 @@ function validateStationId(stationId) {
108621
108868
  }
108622
108869
  }
108623
108870
  function sha256File(filePath) {
108624
- return createHash27("sha256").update(readFileSync37(filePath)).digest("hex");
108871
+ return createHash27("sha256").update(readFileSync38(filePath)).digest("hex");
108625
108872
  }
108626
108873
  function scanHome(definition, homesRoot) {
108627
108874
  const homePath = homePathFor(definition, homesRoot);
@@ -109450,7 +109697,7 @@ var init_codex_hook_policy_recovery = __esm(() => {
109450
109697
  });
109451
109698
 
109452
109699
  // src/lib/agent-codex-trust.ts
109453
- import { lstatSync as lstatSync29, mkdirSync as mkdirSync26, readdirSync as readdirSync21, readFileSync as readFileSync38, realpathSync as realpathSync14, statSync as statSync21 } from "fs";
109700
+ import { lstatSync as lstatSync29, mkdirSync as mkdirSync26, readdirSync as readdirSync21, readFileSync as readFileSync39, realpathSync as realpathSync14, statSync as statSync21 } from "fs";
109454
109701
  import { createHash as createHash28, randomUUID as randomUUID10 } from "crypto";
109455
109702
  import { execFileSync } from "child_process";
109456
109703
  import { dirname as dirname32, isAbsolute as isAbsolute26, join as join58, resolve as resolve23 } from "path";
@@ -109460,13 +109707,13 @@ function verifyReleaseArtifact(proof, skillsCli) {
109460
109707
  need4(isAbsolute26(proof.packageTarPath) && !proof.packageTarPath.includes("\x00"), "RECONCILE_RELEASE_PROVENANCE_PATH");
109461
109708
  const tarPath = realpathSync14(proof.packageTarPath);
109462
109709
  need4(statSync21(tarPath).isFile(), "RECONCILE_RELEASE_PROVENANCE_PATH");
109463
- const tarBytes = readFileSync38(tarPath);
109710
+ const tarBytes = readFileSync39(tarPath);
109464
109711
  need4(tarBytes.byteLength === proof.packageTarBytes && createHash28("sha256").update(tarBytes).digest("hex") === proof.packageTarSha256, "RECONCILE_RELEASE_ARTIFACT_CHANGED");
109465
109712
  const packageRoot = dirname32(dirname32(realpathSync14(skillsCli.receipt.path)));
109466
- const manifest = readFileSync38(join58(packageRoot, "package.json"));
109713
+ const manifest = readFileSync39(join58(packageRoot, "package.json"));
109467
109714
  need4(createHash28("sha256").update(manifest).digest("hex") === skillsCli.receipt.manifestSha256 && skillsCli.receipt.manifestSha256 === proof.manifestSha256, "RECONCILE_RELEASE_MANIFEST_CHANGED");
109468
- need4(createHash28("sha256").update(readFileSync38(skillsCli.receipt.path)).digest("hex") === proof.executableSha256 && skillsCli.receipt.sha256 === proof.executableSha256, "RECONCILE_RELEASE_EXECUTABLE_CHANGED");
109469
- const members2 = [["package/package.json", manifest], ["package/bin/index.js", readFileSync38(skillsCli.receipt.path)]];
109715
+ need4(createHash28("sha256").update(readFileSync39(skillsCli.receipt.path)).digest("hex") === proof.executableSha256 && skillsCli.receipt.sha256 === proof.executableSha256, "RECONCILE_RELEASE_EXECUTABLE_CHANGED");
109716
+ const members2 = [["package/package.json", manifest], ["package/bin/index.js", readFileSync39(skillsCli.receipt.path)]];
109470
109717
  for (const [member, expected] of members2) {
109471
109718
  let actual;
109472
109719
  try {
@@ -109867,7 +110114,8 @@ var init_hook_diagnostics = __esm(() => {
109867
110114
  "SESSION_RECEIPT_CHANGED",
109868
110115
  "SESSION_RECONCILIATION_INCOMPLETE",
109869
110116
  "SESSION_WRITE_LOCKED",
109870
- "SESSION_WRITE_LOCK_CHANGED"
110117
+ "SESSION_WRITE_LOCK_CHANGED",
110118
+ "SESSION_LOCK_RECOVERY_INCOMPLETE"
109871
110119
  ]);
109872
110120
  HookDiagnosticError = class HookDiagnosticError extends Error {
109873
110121
  code;
@@ -109885,7 +110133,7 @@ var exports_agent_integration = {};
109885
110133
  __export(exports_agent_integration, {
109886
110134
  registerAgentIntegration: () => registerAgentIntegration
109887
110135
  });
109888
- import { readFileSync as readFileSync39 } from "fs";
110136
+ import { readFileSync as readFileSync40 } from "fs";
109889
110137
  import { isAbsolute as isAbsolute27 } from "path";
109890
110138
  function pinnedHookProfile(input3, configuredProfile) {
109891
110139
  try {
@@ -109963,7 +110211,7 @@ function registerAgentIntegration(parent) {
109963
110211
  });
109964
110212
  hook.command("install").option("--agent <agent>", `Agent to configure: ${INTEGRATION_AGENTS.join(", ")}, all`, "all").option("--command <path>", "Skills executable used by the hook (preserves existing binding; new agents use skills)").option("--selection-profile <id>", "Selection profile (preserves existing binding; new agents use default)").option("--include-vendor", "Retained for compatibility; vendor system skills are always inventoried and disabled", false).option("--discovery-inputs <file>", "Advanced reviewed active plugin roots and source hashes for unsupported registrations").option("--allow-root-aliases", "Allow home .claude/.codex aliases to existing directories within this home", false).option("--apply", "Apply the plan, preserving prior configuration in private backups", false).option("--json", "Output a receipt as JSON", false).description("Plan or install one Skills CLI bridge plus native prompt hooks").action(async (options) => {
109965
110213
  try {
109966
- const discoveryInputs = options.discoveryInputs ? JSON.parse(readFileSync39(options.discoveryInputs, "utf8")) : undefined;
110214
+ const discoveryInputs = options.discoveryInputs ? JSON.parse(readFileSync40(options.discoveryInputs, "utf8")) : undefined;
109967
110215
  const plan = planAgentIntegration({ agents: agents(options.agent), command: options.command, profileId: options.selectionProfile, includeVendor: options.includeVendor, discoveryInputs, allowRootAliases: options.allowRootAliases });
109968
110216
  const result2 = options.apply ? applyAgentIntegration(plan) : { changed: [], backups: [] };
109969
110217
  const receipt = { applied: options.apply, planned: plan.changes.map((change) => change.path), ...result2, rootAliases: plan.rootAliases ?? [], discovery: plan.discoveryAfter, nativeSkills: plan.nativeSkills.map((entry) => ({ agent: entry.agent, path: entry.path, managed: entry.managed, vendor: entry.vendor, system: entry.system === true, bridge: entry.bridge === true })), requiresNativeRetirement: plan.nativeSkills.some((entry) => !entry.bridge && !entry.system) };
@@ -110021,7 +110269,7 @@ function registerAgentIntegration(parent) {
110021
110269
  try {
110022
110270
  if (agents(options.agent).length !== 1)
110023
110271
  throw new Error("A hook invocation requires one agent");
110024
- const inputText = readFileSync39(0, "utf8");
110272
+ const inputText = readFileSync40(0, "utf8");
110025
110273
  if (inputText.length > 1024 * 1024)
110026
110274
  throw new Error("Hook input is too large");
110027
110275
  let input3 = JSON.parse(inputText);
@@ -110117,7 +110365,7 @@ function registerAgentIntegration(parent) {
110117
110365
  const migrate = parent.command("migrate").description("Preserve and retire native agent skill copies");
110118
110366
  migrate.command("native").option("--project <directory>", "Also inventory a project and its ancestors (the current directory and its ancestors are always included)").option("--include-unmanaged", "Archive user-authored skills as well as Skills-managed copies", false).option("--include-vendor", "Retire vendor SKILL.md discovery files while preserving plugin scripts and assets", false).option("--target-manifest <file>", "Reviewed exact native migration target manifest").option("--discovery-inputs <file>", "Advanced reviewed active plugin roots and source hashes").option("--allow-root-aliases", "Allow home .claude/.codex aliases to existing directories within this home", false).option("--apply", "Move selected skills to private archives outside agent discovery roots", false).option("--json", "Output inventory and archive receipt as JSON", false).description("Inventory native skill copies; preserve complete directories before retiring them").action(async (options) => {
110119
110367
  try {
110120
- const discoveryInputs = options.discoveryInputs ? JSON.parse(readFileSync39(options.discoveryInputs, "utf8")) : undefined;
110368
+ const discoveryInputs = options.discoveryInputs ? JSON.parse(readFileSync40(options.discoveryInputs, "utf8")) : undefined;
110121
110369
  if (options.targetManifest && (options.includeUnmanaged || options.includeVendor))
110122
110370
  throw new Error("--target-manifest cannot be combined with broad native migration selectors");
110123
110371
  const targetManifest = options.targetManifest ? readNativeMigrationTargetManifest(options.targetManifest) : undefined;
@@ -110424,7 +110672,7 @@ import {
110424
110672
  copyFileSync as copyFileSync2,
110425
110673
  mkdirSync as mkdirSync27,
110426
110674
  readdirSync as readdirSync22,
110427
- readFileSync as readFileSync40,
110675
+ readFileSync as readFileSync41,
110428
110676
  statSync as statSync22,
110429
110677
  writeFileSync as writeFileSync27
110430
110678
  } from "fs";
@@ -110440,7 +110688,7 @@ function readSnapshotManifest(repoRoot, stationId) {
110440
110688
  const manifestPath = join59(snapshotRoot, "sync-manifest.json");
110441
110689
  let manifest;
110442
110690
  try {
110443
- manifest = JSON.parse(readFileSync40(manifestPath, "utf8"));
110691
+ manifest = JSON.parse(readFileSync41(manifestPath, "utf8"));
110444
110692
  } catch (error61) {
110445
110693
  fail5("MANIFEST_UNREADABLE", `cannot read snapshot manifest: ${manifestPath}: ${error61.message}`);
110446
110694
  }
@@ -110576,7 +110824,7 @@ function planStationHydration(stationId, repoRoot) {
110576
110824
  for (const copy of copies) {
110577
110825
  let isStub = false;
110578
110826
  try {
110579
- isStub = isPointerSkillMd(readFileSync40(copy.fullPath, "utf8"));
110827
+ isStub = isPointerSkillMd(readFileSync41(copy.fullPath, "utf8"));
110580
110828
  } catch {
110581
110829
  isStub = false;
110582
110830
  }
@@ -110780,7 +111028,7 @@ var init_hydrate = __esm(() => {
110780
111028
 
110781
111029
  // src/lib/prepare-skill.ts
110782
111030
  import { createHash as createHash30, randomUUID as randomUUID11 } from "crypto";
110783
- import { chmodSync as chmodSync4, existsSync as existsSync34, lstatSync as lstatSync30, mkdirSync as mkdirSync28, mkdtempSync as mkdtempSync6, readFileSync as readFileSync41, readdirSync as readdirSync23, renameSync as renameSync13, rmSync as rmSync9, writeFileSync as writeFileSync28 } from "fs";
111031
+ import { chmodSync as chmodSync4, existsSync as existsSync34, lstatSync as lstatSync30, mkdirSync as mkdirSync28, mkdtempSync as mkdtempSync6, readFileSync as readFileSync42, readdirSync as readdirSync23, renameSync as renameSync13, rmSync as rmSync9, writeFileSync as writeFileSync28 } from "fs";
110784
111032
  import { tmpdir as tmpdir2 } from "os";
110785
111033
  import { dirname as dirname34, isAbsolute as isAbsolute28, join as join60, relative as relative9, resolve as resolve25, sep as sep12 } from "path";
110786
111034
  function prepareSkill(name, options) {
@@ -111000,7 +111248,7 @@ function snapshot2(root2) {
111000
111248
  bytes += stat3.size;
111001
111249
  if (bytes > 50000000)
111002
111250
  throw new Error("Skill exceeds the preparation size limit (50000000 bytes).");
111003
- const content = readFileSync41(absolute);
111251
+ const content = readFileSync42(absolute);
111004
111252
  if (content.length !== stat3.size)
111005
111253
  throw new Error("Skill changed during preparation.");
111006
111254
  files.push({ path, bytes: content, mode: stat3.mode & 511 });
@@ -111682,8 +111930,8 @@ __export(exports_publish, {
111682
111930
  PushSkillError: () => PushSkillError
111683
111931
  });
111684
111932
  import { execFileSync as execFileSync2 } from "child_process";
111685
- import { existsSync as existsSync35, readFileSync as readFileSync42 } from "fs";
111686
- import { hostname as hostname4 } from "os";
111933
+ import { existsSync as existsSync35, readFileSync as readFileSync43 } from "fs";
111934
+ import { hostname as hostname5 } from "os";
111687
111935
  import { join as join61 } from "path";
111688
111936
  function registerPublish(parent) {
111689
111937
  parent.command("push").argument("<name>", "Name of a skill in the local corpus (~/.hasna/skills/installed or the migrated ~/.hasna/skills/skills)").option("--version <version>", "Override the version recorded on the instance").option("--force-new-version", "If name@version already exists with different content, publish as the next patch version", false).option("--dry-run", "Pack and validate without uploading", false).option("--json", "Output result as JSON", false).description("Publish a local skill to the configured skills instance").action(async (name, options) => {
@@ -111737,7 +111985,7 @@ async function pushSkill(name, options = {}) {
111737
111985
  await verifyPackedCanonicalHash(skill.name, packed);
111738
111986
  const versionManifest = buildVersionManifest(skill.path, packed);
111739
111987
  const skillMdPath = join61(skill.path, "SKILL.md");
111740
- const skillMd = existsSync35(skillMdPath) ? readFileSync42(skillMdPath, "utf-8") : undefined;
111988
+ const skillMd = existsSync35(skillMdPath) ? readFileSync43(skillMdPath, "utf-8") : undefined;
111741
111989
  const base3 = {
111742
111990
  slug: skill.name,
111743
111991
  path: skill.path,
@@ -111867,7 +112115,7 @@ function buildVersionManifest(skillDir, packed) {
111867
112115
  unpackedByteSize: packed.unpackedByteSize,
111868
112116
  bundleSha256: packed.sha256,
111869
112117
  provenance: {
111870
- machine: hostname4(),
112118
+ machine: hostname5(),
111871
112119
  agent: process.env.SKILLS_AGENT_ID ?? process.env.HASNA_AGENT_ID ?? process.env.AGENT_ID ?? null,
111872
112120
  cliVersion: package_default.version,
111873
112121
  gitRemote: sanitizeGitRemote(gitValue(skillDir, ["remote", "get-url", "origin"])),
@@ -113456,7 +113704,7 @@ var init_storage2 = __esm(() => {
113456
113704
  });
113457
113705
 
113458
113706
  // src/lib/registry-reconcile.ts
113459
- import { existsSync as existsSync36, readFileSync as readFileSync43, statSync as statSync23, writeFileSync as writeFileSync30 } from "fs";
113707
+ import { existsSync as existsSync36, readFileSync as readFileSync44, statSync as statSync23, writeFileSync as writeFileSync30 } from "fs";
113460
113708
  import { join as join62 } from "path";
113461
113709
  function isDirectory2(path) {
113462
113710
  try {
@@ -113476,7 +113724,7 @@ function readBaseline(skillDir) {
113476
113724
  if (!existsSync36(markerPath))
113477
113725
  return;
113478
113726
  try {
113479
- const marker = JSON.parse(readFileSync43(markerPath, "utf-8"));
113727
+ const marker = JSON.parse(readFileSync44(markerPath, "utf-8"));
113480
113728
  if (!isSkillsOwnershipMarker(marker))
113481
113729
  return;
113482
113730
  return {
@@ -113492,7 +113740,7 @@ function readCursor(root2) {
113492
113740
  if (!existsSync36(path))
113493
113741
  return { runCount: 0 };
113494
113742
  try {
113495
- const cursor2 = JSON.parse(readFileSync43(path, "utf-8"));
113743
+ const cursor2 = JSON.parse(readFileSync44(path, "utf-8"));
113496
113744
  return { runCount: typeof cursor2.runCount === "number" ? cursor2.runCount : 0 };
113497
113745
  } catch {
113498
113746
  return { runCount: 0 };
@@ -122009,8 +122257,7 @@ program2.name("skills").description("Discover and run AI agent skills through th
122009
122257
  program2.hook("preAction", () => {
122010
122258
  const profile = program2.opts().profile;
122011
122259
  recordEnvironmentProfile(process.env.HASNA_PROFILE);
122012
- if (profile !== undefined)
122013
- process.env.HASNA_PROFILE = profile;
122260
+ selectCliSkillsCredentialProfile(profile);
122014
122261
  });
122015
122262
  program2.command("interactive", { isDefault: true }).alias("i").allowExcessArguments(true).description("Interactive skill browser (TUI)").action(async (_options, command) => {
122016
122263
  const stray = command.args[0];