@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/README.md +32 -0
- package/bin/index.js +379 -132
- package/bin/mcp.js +245 -49
- package/bin/migrate.js +2 -6
- package/bin/server.js +5 -6
- package/bin/worker.js +2 -6
- package/dist/cli/profile-selection.d.ts +1 -1
- package/dist/index.js +257 -67
- package/dist/lib/cli-credential-profile.d.ts +2 -0
- package/dist/lib/selection-cache.d.ts +12 -0
- package/dist/sdk/index.js +330 -141
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6988,7 +6988,7 @@ var require_public_api = __commonJS((exports) => {
|
|
|
6988
6988
|
});
|
|
6989
6989
|
|
|
6990
6990
|
// src/lib/registry.ts
|
|
6991
|
-
import { existsSync as existsSync14, readFileSync as
|
|
6991
|
+
import { existsSync as existsSync14, readFileSync as readFileSync18, readdirSync as readdirSync11 } from "fs";
|
|
6992
6992
|
import { join as join29 } from "path";
|
|
6993
6993
|
|
|
6994
6994
|
// src/lib/config.ts
|
|
@@ -9091,7 +9091,7 @@ function assertAgentPolicyCollections(policy) {
|
|
|
9091
9091
|
|
|
9092
9092
|
// src/lib/agent-discovery.ts
|
|
9093
9093
|
import { createHash as createHash16 } from "crypto";
|
|
9094
|
-
import { lstatSync as lstatSync20, readFileSync as
|
|
9094
|
+
import { lstatSync as lstatSync20, readFileSync as readFileSync17, readdirSync as readdirSync9, realpathSync as realpathSync4 } from "fs";
|
|
9095
9095
|
import { basename as basename8, dirname as dirname16, isAbsolute as isAbsolute14, join as join26, resolve as resolve14, sep as sep5 } from "path";
|
|
9096
9096
|
import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
|
|
9097
9097
|
|
|
@@ -9611,7 +9611,7 @@ import { isAbsolute as isAbsolute11, join as join23, resolve as resolve11 } from
|
|
|
9611
9611
|
// package.json
|
|
9612
9612
|
var package_default = {
|
|
9613
9613
|
name: "@hasna/skills",
|
|
9614
|
-
version: "0.10.
|
|
9614
|
+
version: "0.10.2",
|
|
9615
9615
|
description: "Skills library for AI coding agents",
|
|
9616
9616
|
type: "module",
|
|
9617
9617
|
bin: {
|
|
@@ -10569,9 +10569,17 @@ var AUTHORITY_OVERRIDE_HEADERS = new Set([
|
|
|
10569
10569
|
|
|
10570
10570
|
// src/lib/instance-credentials.ts
|
|
10571
10571
|
import { closeSync as closeSync5, constants as constants2, fstatSync as fstatSync5, lstatSync as lstatSync8, openSync as openSync5, readSync as readSync2 } from "fs";
|
|
10572
|
+
|
|
10573
|
+
// src/lib/cli-credential-profile.ts
|
|
10574
|
+
var cliCredentialProfile;
|
|
10575
|
+
function selectedCliSkillsCredentialProfile() {
|
|
10576
|
+
return cliCredentialProfile;
|
|
10577
|
+
}
|
|
10578
|
+
|
|
10579
|
+
// src/lib/instance-credentials.ts
|
|
10572
10580
|
var SKILLS_BOUND_API_URL = "HASNA_SKILLS_BOUND_API_URL";
|
|
10573
10581
|
function selectedSkillsProfile(env, explicit) {
|
|
10574
|
-
const selected = explicit ?? env.HASNA_PROFILE;
|
|
10582
|
+
const selected = explicit ?? selectedCliSkillsCredentialProfile() ?? env.HASNA_PROFILE;
|
|
10575
10583
|
if (selected === undefined)
|
|
10576
10584
|
return null;
|
|
10577
10585
|
const profile = selected.trim();
|
|
@@ -10819,11 +10827,13 @@ function snapshotSkillsEnvironment(env) {
|
|
|
10819
10827
|
return Object.freeze(snapshot);
|
|
10820
10828
|
}
|
|
10821
10829
|
function snapshotSkillsOptions(env, options) {
|
|
10830
|
+
const profile = options.credentials?.profile ?? selectedCliSkillsCredentialProfile();
|
|
10831
|
+
const credentials = profile === undefined ? options.credentials : { ...options.credentials, profile };
|
|
10822
10832
|
if (env !== process.env)
|
|
10823
|
-
return options;
|
|
10824
|
-
return { ...options, credentials: { ...
|
|
10825
|
-
...
|
|
10826
|
-
enabled:
|
|
10833
|
+
return credentials === options.credentials ? options : { ...options, credentials };
|
|
10834
|
+
return { ...options, credentials: { ...credentials, keychain: {
|
|
10835
|
+
...credentials?.keychain,
|
|
10836
|
+
enabled: credentials?.keychain?.enabled ?? true
|
|
10827
10837
|
} } };
|
|
10828
10838
|
}
|
|
10829
10839
|
function resolveSkillsFleetOrThrow(env, options) {
|
|
@@ -10911,8 +10921,9 @@ async function resolveSkillsApiKey(env = process.env, options = {}) {
|
|
|
10911
10921
|
}
|
|
10912
10922
|
async function resolveSkillsConnection(env = process.env, options = {}) {
|
|
10913
10923
|
const snapshotEnv = snapshotSkillsEnvironment(env);
|
|
10914
|
-
const
|
|
10915
|
-
const
|
|
10924
|
+
const resolvedOptions = snapshotSkillsOptions(env, options);
|
|
10925
|
+
const assertFilesUnchanged = selectsSkillsLocalMode(snapshotEnv) ? () => {} : captureSkillsCredentialFiles(skillsProfileCredentialFiles(snapshotEnv, resolvedOptions.credentials?.profile));
|
|
10926
|
+
const fleet = resolveSkillsFleet(snapshotEnv, resolvedOptions);
|
|
10916
10927
|
if (fleet.mode === "local" && env === process.env)
|
|
10917
10928
|
noticeLocalSkillsMode();
|
|
10918
10929
|
if (fleet.mode !== "hosted")
|
|
@@ -11812,7 +11823,9 @@ function tarOctal(field) {
|
|
|
11812
11823
|
|
|
11813
11824
|
// src/lib/selection-cache.ts
|
|
11814
11825
|
import { createHash as createHash7, randomUUID } from "crypto";
|
|
11815
|
-
import {
|
|
11826
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
11827
|
+
import { closeSync as closeSync6, constants as constants3, fstatSync as fstatSync6, fsyncSync, lstatSync as lstatSync9, mkdirSync as mkdirSync3, openSync as openSync6, readFileSync as readFileSync9, readlinkSync as readlinkSync2, readSync as readSync3, renameSync, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
11828
|
+
import { hostname } from "os";
|
|
11816
11829
|
import { dirname as dirname8, join as join12, parse as parse2, resolve as resolve7 } from "path";
|
|
11817
11830
|
import { isDeepStrictEqual } from "util";
|
|
11818
11831
|
|
|
@@ -12113,6 +12126,166 @@ function readSkillSessionSnapshot(sessionId, options = {}) {
|
|
|
12113
12126
|
function skillSessionSnapshotBinding(snapshot) {
|
|
12114
12127
|
return { sessionId: snapshot.sessionId, generation: snapshot.generation, receiptSha256: snapshot.receiptSha256 };
|
|
12115
12128
|
}
|
|
12129
|
+
var SESSION_LOCK_MAX_BYTES = 4096;
|
|
12130
|
+
var SESSION_LOCK_MIN_AGE_MS = 30000;
|
|
12131
|
+
function localBootId() {
|
|
12132
|
+
try {
|
|
12133
|
+
if (process.platform === "linux") {
|
|
12134
|
+
const value = readFileSync9("/proc/sys/kernel/random/boot_id", "utf8").trim();
|
|
12135
|
+
return /^[a-f0-9-]{36}$/i.test(value) ? value : null;
|
|
12136
|
+
}
|
|
12137
|
+
if (process.platform === "darwin") {
|
|
12138
|
+
const result = spawnSync2("/usr/sbin/sysctl", ["-n", "kern.boottime"], { encoding: "utf8", timeout: 3000, env: { LC_ALL: "C" } });
|
|
12139
|
+
if (result.status !== 0 || result.error)
|
|
12140
|
+
return null;
|
|
12141
|
+
const seconds = /\bsec\s*=\s*(\d+)\b/.exec(result.stdout)?.[1];
|
|
12142
|
+
return seconds ? `darwin:${seconds}` : null;
|
|
12143
|
+
}
|
|
12144
|
+
} catch {}
|
|
12145
|
+
return null;
|
|
12146
|
+
}
|
|
12147
|
+
function processStart(pid) {
|
|
12148
|
+
if (!Number.isSafeInteger(pid) || pid <= 0)
|
|
12149
|
+
return { state: "unknown" };
|
|
12150
|
+
if (process.platform === "linux") {
|
|
12151
|
+
try {
|
|
12152
|
+
const stat = readFileSync9(`/proc/${pid}/stat`, "utf8");
|
|
12153
|
+
const close = stat.lastIndexOf(")");
|
|
12154
|
+
const start = close < 0 ? undefined : stat.slice(close + 2).trim().split(/\s+/)[19];
|
|
12155
|
+
return start && /^\d+$/.test(start) ? { state: "alive", start: `linux:${start}` } : { state: "unknown" };
|
|
12156
|
+
} catch (error) {
|
|
12157
|
+
return { state: error.code === "ENOENT" ? "absent" : "unknown" };
|
|
12158
|
+
}
|
|
12159
|
+
}
|
|
12160
|
+
if (process.platform === "darwin") {
|
|
12161
|
+
const result = spawnSync2("/bin/ps", ["-p", String(pid), "-o", "lstart="], { encoding: "utf8", timeout: 3000, env: { LC_ALL: "C" } });
|
|
12162
|
+
if (result.error || result.signal)
|
|
12163
|
+
return { state: "unknown" };
|
|
12164
|
+
const start = result.stdout.trim();
|
|
12165
|
+
if (result.status === 1 && !start && !result.stderr.trim())
|
|
12166
|
+
return { state: "absent" };
|
|
12167
|
+
return result.status === 0 && start ? { state: "alive", start: `darwin:${start}` } : { state: "unknown" };
|
|
12168
|
+
}
|
|
12169
|
+
return { state: "unknown" };
|
|
12170
|
+
}
|
|
12171
|
+
function localLockIdentity() {
|
|
12172
|
+
const bootId = localBootId(), owner = processStart(process.pid);
|
|
12173
|
+
if (!bootId || owner.state !== "alive")
|
|
12174
|
+
return null;
|
|
12175
|
+
let pidNamespace;
|
|
12176
|
+
if (process.platform === "linux") {
|
|
12177
|
+
try {
|
|
12178
|
+
pidNamespace = readlinkSync2("/proc/self/ns/pid");
|
|
12179
|
+
} catch {
|
|
12180
|
+
return null;
|
|
12181
|
+
}
|
|
12182
|
+
if (!/^pid:\[\d+\]$/.test(pidNamespace))
|
|
12183
|
+
return null;
|
|
12184
|
+
}
|
|
12185
|
+
return { host: hostname(), bootId, pidNamespace, processStart: owner.start };
|
|
12186
|
+
}
|
|
12187
|
+
function readSessionLock(sessionId, options) {
|
|
12188
|
+
const path = `${sessionReceiptPath(sessionId, options)}.write-lock`;
|
|
12189
|
+
const before = lstatSync9(path, { throwIfNoEntry: false });
|
|
12190
|
+
if (!before)
|
|
12191
|
+
return null;
|
|
12192
|
+
if (!before.isFile() || before.nlink !== 1 || process.getuid && before.uid !== process.getuid()) {
|
|
12193
|
+
throw new SkillSelectionError("SESSION_WRITE_LOCKED", "The session lock is not a private regular file; recovery requires review.");
|
|
12194
|
+
}
|
|
12195
|
+
const bytes = readRegularFile(path, SESSION_LOCK_MAX_BYTES);
|
|
12196
|
+
const after = lstatSync9(path, { throwIfNoEntry: false });
|
|
12197
|
+
if (!bytes || !after?.isFile() || before.dev !== after.dev || before.ino !== after.ino || before.mtimeMs !== after.mtimeMs) {
|
|
12198
|
+
throw new SkillSelectionError("SESSION_WRITE_LOCKED", "The session lock changed during inspection; recovery requires review.");
|
|
12199
|
+
}
|
|
12200
|
+
let marker;
|
|
12201
|
+
try {
|
|
12202
|
+
marker = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
12203
|
+
} catch {
|
|
12204
|
+
throw new SkillSelectionError("SESSION_WRITE_LOCKED", "The session lock is unreadable; recovery requires review.");
|
|
12205
|
+
}
|
|
12206
|
+
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)) {
|
|
12207
|
+
throw new SkillSelectionError("SESSION_WRITE_LOCKED", "The session lock has invalid ownership metadata; recovery requires review.");
|
|
12208
|
+
}
|
|
12209
|
+
return { path, bytes, marker, sha256: sha256Hex(bytes), dev: after.dev, ino: after.ino, mtimeMs: after.mtimeMs };
|
|
12210
|
+
}
|
|
12211
|
+
function writerIsGone(lock, explicitLocalHost) {
|
|
12212
|
+
if (Date.now() - lock.mtimeMs < SESSION_LOCK_MIN_AGE_MS)
|
|
12213
|
+
return false;
|
|
12214
|
+
const owner = processStart(lock.marker.pid);
|
|
12215
|
+
if (owner.state === "unknown")
|
|
12216
|
+
return false;
|
|
12217
|
+
if (lock.marker.schemaVersion === 1)
|
|
12218
|
+
return explicitLocalHost && owner.state === "absent";
|
|
12219
|
+
const local = localLockIdentity();
|
|
12220
|
+
if (!local || lock.marker.host !== local.host || lock.marker.bootId !== local.bootId || lock.marker.pidNamespace !== local.pidNamespace)
|
|
12221
|
+
return false;
|
|
12222
|
+
return owner.state === "absent" || owner.state === "alive" && owner.start !== lock.marker.processStart;
|
|
12223
|
+
}
|
|
12224
|
+
function archiveSessionLock(lock, receipt, explicitLocalHost) {
|
|
12225
|
+
const guardPath = `${lock.path}.recovery-guard`;
|
|
12226
|
+
let guardFd;
|
|
12227
|
+
try {
|
|
12228
|
+
guardFd = openSync6(guardPath, constants3.O_WRONLY | constants3.O_CREAT | constants3.O_EXCL | constants3.O_NOFOLLOW, 384);
|
|
12229
|
+
} catch (error) {
|
|
12230
|
+
if (error.code === "EEXIST")
|
|
12231
|
+
return null;
|
|
12232
|
+
throw error;
|
|
12233
|
+
}
|
|
12234
|
+
const guardStat = fstatSync6(guardFd);
|
|
12235
|
+
try {
|
|
12236
|
+
writeFileSync3(guardFd, `${JSON.stringify({ schemaVersion: 1, pid: process.pid, operationId: randomUUID() })}
|
|
12237
|
+
`);
|
|
12238
|
+
fsyncSync(guardFd);
|
|
12239
|
+
const cacheOptions = { cacheDir: dirname8(dirname8(lock.path)) };
|
|
12240
|
+
const current = readSessionLock(lock.marker.sessionId, cacheOptions);
|
|
12241
|
+
if (!current || current.dev !== lock.dev || current.ino !== lock.ino || current.sha256 !== lock.sha256 || current.mtimeMs !== lock.mtimeMs || !writerIsGone(current, explicitLocalHost))
|
|
12242
|
+
return null;
|
|
12243
|
+
const currentReceipt = readSkillSessionSnapshotIfExists(lock.marker.sessionId, cacheOptions);
|
|
12244
|
+
if (currentReceipt?.sha256 !== receipt?.sha256 || currentReceipt?.generation !== receipt?.generation)
|
|
12245
|
+
return null;
|
|
12246
|
+
const directory = join12(dirname8(dirname8(lock.path)), "session-lock-recoveries", randomUUID());
|
|
12247
|
+
const archivePath = join12(directory, "original.write-lock");
|
|
12248
|
+
const recordPath = join12(directory, "recovery.json");
|
|
12249
|
+
assertRegularPath(archivePath, true);
|
|
12250
|
+
archiveBytes(recordPath, Buffer.from(`${JSON.stringify({
|
|
12251
|
+
schemaVersion: 1,
|
|
12252
|
+
sessionId: lock.marker.sessionId,
|
|
12253
|
+
originalPath: lock.path,
|
|
12254
|
+
lockSha256: lock.sha256,
|
|
12255
|
+
lockMtime: new Date(lock.mtimeMs).toISOString(),
|
|
12256
|
+
lockPid: lock.marker.pid,
|
|
12257
|
+
receiptSha256: receipt?.sha256 ?? null,
|
|
12258
|
+
receiptGeneration: receipt?.generation ?? null,
|
|
12259
|
+
status: "prepared"
|
|
12260
|
+
})}
|
|
12261
|
+
`));
|
|
12262
|
+
syncDirectory(directory);
|
|
12263
|
+
syncDirectory(dirname8(directory));
|
|
12264
|
+
const finalLock = readSessionLock(lock.marker.sessionId, cacheOptions);
|
|
12265
|
+
if (!finalLock || finalLock.dev !== lock.dev || finalLock.ino !== lock.ino || finalLock.sha256 !== lock.sha256 || readSkillSessionSnapshotIfExists(lock.marker.sessionId, cacheOptions)?.sha256 !== receipt?.sha256)
|
|
12266
|
+
return null;
|
|
12267
|
+
let moved = false;
|
|
12268
|
+
try {
|
|
12269
|
+
renameSync(lock.path, archivePath);
|
|
12270
|
+
moved = true;
|
|
12271
|
+
syncDirectory(directory);
|
|
12272
|
+
syncDirectory(dirname8(lock.path));
|
|
12273
|
+
if (sha256Hex(readRegularFile(archivePath, SESSION_LOCK_MAX_BYTES)) !== lock.sha256) {
|
|
12274
|
+
throw new Error("Archived lock bytes changed");
|
|
12275
|
+
}
|
|
12276
|
+
} catch (error) {
|
|
12277
|
+
if (moved)
|
|
12278
|
+
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.");
|
|
12279
|
+
throw error;
|
|
12280
|
+
}
|
|
12281
|
+
return archivePath;
|
|
12282
|
+
} finally {
|
|
12283
|
+
closeSync6(guardFd);
|
|
12284
|
+
const current = lstatSync9(guardPath, { throwIfNoEntry: false });
|
|
12285
|
+
if (current?.isFile() && current.dev === guardStat.dev && current.ino === guardStat.ino)
|
|
12286
|
+
unlinkSync(guardPath);
|
|
12287
|
+
}
|
|
12288
|
+
}
|
|
12116
12289
|
function withSessionWriteLocks(sessionIds, options, action) {
|
|
12117
12290
|
const operationId = randomUUID();
|
|
12118
12291
|
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);
|
|
@@ -12132,13 +12305,30 @@ function withSessionWriteLocks(sessionIds, options, action) {
|
|
|
12132
12305
|
try {
|
|
12133
12306
|
fd = openSync6(lock.path, constants3.O_WRONLY | constants3.O_CREAT | constants3.O_EXCL | constants3.O_NOFOLLOW, 384);
|
|
12134
12307
|
} catch (error) {
|
|
12135
|
-
if (error.code
|
|
12136
|
-
throw
|
|
12137
|
-
|
|
12308
|
+
if (error.code !== "EEXIST")
|
|
12309
|
+
throw error;
|
|
12310
|
+
try {
|
|
12311
|
+
const stale = readSessionLock(lock.sessionId, options);
|
|
12312
|
+
const receipt = stale && readSkillSessionSnapshotIfExists(lock.sessionId, options);
|
|
12313
|
+
if (stale?.marker.schemaVersion === 2 && writerIsGone(stale, false)) {
|
|
12314
|
+
archiveSessionLock(stale, receipt, false);
|
|
12315
|
+
}
|
|
12316
|
+
} catch (recoveryError) {
|
|
12317
|
+
if (recoveryError instanceof SkillSelectionError && recoveryError.code === "SESSION_LOCK_RECOVERY_INCOMPLETE")
|
|
12318
|
+
throw recoveryError;
|
|
12319
|
+
}
|
|
12320
|
+
try {
|
|
12321
|
+
fd = openSync6(lock.path, constants3.O_WRONLY | constants3.O_CREAT | constants3.O_EXCL | constants3.O_NOFOLLOW, 384);
|
|
12322
|
+
} catch (retryError) {
|
|
12323
|
+
if (retryError.code === "EEXIST")
|
|
12324
|
+
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.");
|
|
12325
|
+
throw retryError;
|
|
12326
|
+
}
|
|
12138
12327
|
}
|
|
12139
12328
|
const stat = fstatSync6(fd);
|
|
12140
12329
|
owned.push({ path: lock.path, fd, dev: stat.dev, ino: stat.ino });
|
|
12141
|
-
|
|
12330
|
+
const identity3 = localLockIdentity();
|
|
12331
|
+
writeFileSync3(fd, `${JSON.stringify({ schemaVersion: identity3 ? 2 : 1, operationId, sessionId: lock.sessionId, pid: process.pid, ...identity3 })}
|
|
12142
12332
|
`);
|
|
12143
12333
|
}
|
|
12144
12334
|
return action(assertOwned);
|
|
@@ -12257,7 +12447,7 @@ function replaceSkillSession(expected, replacement, plan, options = {}, beforeCo
|
|
|
12257
12447
|
}
|
|
12258
12448
|
|
|
12259
12449
|
// src/lib/dependency-preparation.ts
|
|
12260
|
-
import { constants as constants4, closeSync as closeSync7, fstatSync as fstatSync7, lstatSync as lstatSync10, mkdirSync as mkdirSync4, openSync as openSync7, readFileSync as
|
|
12450
|
+
import { constants as constants4, 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";
|
|
12261
12451
|
import { join as join13 } from "path";
|
|
12262
12452
|
|
|
12263
12453
|
// src/lib/preparation-process.ts
|
|
@@ -12331,7 +12521,7 @@ function claimPreparation(skillPath) {
|
|
|
12331
12521
|
return;
|
|
12332
12522
|
if (!lstatSync10(state).isFile() || lstatSync10(state).isSymbolicLink() || lstatSync10(state).size > 1024)
|
|
12333
12523
|
return;
|
|
12334
|
-
const previous = JSON.parse(
|
|
12524
|
+
const previous = JSON.parse(readFileSync10(state, "utf8"));
|
|
12335
12525
|
if (previous.version !== 1 || previous.status !== "failed" || Object.keys(previous).length !== 2)
|
|
12336
12526
|
return;
|
|
12337
12527
|
}
|
|
@@ -12464,11 +12654,11 @@ async function prepareSkillDependencies(skillPath, env, timeoutMs = DEFAULT_PREP
|
|
|
12464
12654
|
}
|
|
12465
12655
|
|
|
12466
12656
|
// src/lib/skillinfo.ts
|
|
12467
|
-
import { existsSync as existsSync12, readFileSync as
|
|
12657
|
+
import { existsSync as existsSync12, readFileSync as readFileSync16 } from "fs";
|
|
12468
12658
|
import { join as join20 } from "path";
|
|
12469
12659
|
|
|
12470
12660
|
// src/lib/installer.ts
|
|
12471
|
-
import { existsSync as existsSync11, readFileSync as
|
|
12661
|
+
import { existsSync as existsSync11, readFileSync as readFileSync15, rmSync as rmSync2 } from "fs";
|
|
12472
12662
|
import { join as join19 } from "path";
|
|
12473
12663
|
import { homedir as homedir4 } from "os";
|
|
12474
12664
|
|
|
@@ -12479,7 +12669,7 @@ import {
|
|
|
12479
12669
|
lstatSync as lstatSync15,
|
|
12480
12670
|
mkdirSync as mkdirSync6,
|
|
12481
12671
|
mkdtempSync,
|
|
12482
|
-
readFileSync as
|
|
12672
|
+
readFileSync as readFileSync13,
|
|
12483
12673
|
readdirSync as readdirSync8,
|
|
12484
12674
|
renameSync as renameSync3,
|
|
12485
12675
|
rmSync,
|
|
@@ -12491,7 +12681,7 @@ import { basename as basename5, dirname as dirname11, join as join17 } from "pat
|
|
|
12491
12681
|
|
|
12492
12682
|
// src/lib/agent-integration.ts
|
|
12493
12683
|
import { createHash as createHash10, randomUUID as randomUUID2 } from "crypto";
|
|
12494
|
-
import { existsSync as existsSync8, lstatSync as lstatSync14, statSync as statSync7, mkdirSync as mkdirSync5, readFileSync as
|
|
12684
|
+
import { existsSync as existsSync8, lstatSync as lstatSync14, statSync as statSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync12, 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 constants7, linkSync } from "fs";
|
|
12495
12685
|
import { dirname as dirname10, join as join16, resolve as resolve9, relative as relative4, isAbsolute as isAbsolute9, sep as sep4 } from "path";
|
|
12496
12686
|
import { homedir as homedir2 } from "os";
|
|
12497
12687
|
|
|
@@ -12577,7 +12767,7 @@ function requiresCliSkillLoading(dataDir2 = getDataDirReadOnly()) {
|
|
|
12577
12767
|
|
|
12578
12768
|
// src/lib/agent-bridge.ts
|
|
12579
12769
|
import { createHash as createHash8 } from "crypto";
|
|
12580
|
-
import { lstatSync as lstatSync12, readFileSync as
|
|
12770
|
+
import { lstatSync as lstatSync12, readFileSync as readFileSync11, readdirSync as readdirSync6 } from "fs";
|
|
12581
12771
|
import { join as join15 } from "path";
|
|
12582
12772
|
var CLI_BRIDGE_NAME = "skills-cli";
|
|
12583
12773
|
var CLI_BRIDGE_VERSION = 1;
|
|
@@ -12611,7 +12801,7 @@ function isOwnedCliBridge(path, expectedPaths) {
|
|
|
12611
12801
|
return false;
|
|
12612
12802
|
return Object.entries(CLI_BRIDGE_FILES).every(([name, content]) => {
|
|
12613
12803
|
const file = join15(path, name), stat = lstatSync12(file);
|
|
12614
|
-
return stat.isFile() && !stat.isSymbolicLink() && stat.size === Buffer.byteLength(content) &&
|
|
12804
|
+
return stat.isFile() && !stat.isSymbolicLink() && stat.size === Buffer.byteLength(content) && readFileSync11(file, "utf8") === content;
|
|
12615
12805
|
});
|
|
12616
12806
|
} catch {
|
|
12617
12807
|
return false;
|
|
@@ -13011,7 +13201,7 @@ function readRootAlias(home, agent) {
|
|
|
13011
13201
|
const stat = lstatSync14(alias, { throwIfNoEntry: false, bigint: true });
|
|
13012
13202
|
if (!stat?.isSymbolicLink())
|
|
13013
13203
|
throw new Error(`Agent root alias changed after planning: ${alias}`);
|
|
13014
|
-
const link =
|
|
13204
|
+
const link = readlinkSync3(alias), targetPath = resolve9(dirname10(alias), link);
|
|
13015
13205
|
assertSafePath(targetPath);
|
|
13016
13206
|
const targetStat = lstatSync14(targetPath, { throwIfNoEntry: false });
|
|
13017
13207
|
if (!targetStat?.isDirectory())
|
|
@@ -13164,7 +13354,7 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
|
|
|
13164
13354
|
throw new Error("Native skill discovery metadata limit exceeded");
|
|
13165
13355
|
}
|
|
13166
13356
|
function emptySiblingCacheAlias(path, parent) {
|
|
13167
|
-
const link =
|
|
13357
|
+
const link = readlinkSync3(path), target = resolve9(parent, link);
|
|
13168
13358
|
if (dirname10(target) !== parent || (isAbsolute9(link) ? link !== target : dirname10(link) !== "."))
|
|
13169
13359
|
return false;
|
|
13170
13360
|
if (!lstatSync14(target, { throwIfNoEntry: false })?.isDirectory())
|
|
@@ -13193,7 +13383,7 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
|
|
|
13193
13383
|
const marker = join16(path, ".hasna-skills.json");
|
|
13194
13384
|
if (existsSync8(marker)) {
|
|
13195
13385
|
try {
|
|
13196
|
-
managed = JSON.parse(
|
|
13386
|
+
managed = JSON.parse(readFileSync12(marker, "utf8")).managedBy === "@hasna/skills";
|
|
13197
13387
|
} catch {}
|
|
13198
13388
|
}
|
|
13199
13389
|
const bridge = !vendor && isOwnedCliBridge(path, bridgePaths);
|
|
@@ -13266,7 +13456,7 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
|
|
|
13266
13456
|
}
|
|
13267
13457
|
function readOptional(path) {
|
|
13268
13458
|
assertSafePath(path);
|
|
13269
|
-
return existsSync8(path) ?
|
|
13459
|
+
return existsSync8(path) ? readFileSync12(path, "utf8") : null;
|
|
13270
13460
|
}
|
|
13271
13461
|
function jsonObject(text2, path) {
|
|
13272
13462
|
if (text2 === null)
|
|
@@ -13978,7 +14168,7 @@ function hasSkillsOwnershipMarker(dir) {
|
|
|
13978
14168
|
try {
|
|
13979
14169
|
if (!lstatSync15(path).isFile())
|
|
13980
14170
|
return false;
|
|
13981
|
-
const marker = JSON.parse(
|
|
14171
|
+
const marker = JSON.parse(readFileSync13(path, "utf8"));
|
|
13982
14172
|
return isSkillsOwnershipMarker(marker);
|
|
13983
14173
|
} catch {
|
|
13984
14174
|
return false;
|
|
@@ -14187,7 +14377,7 @@ function writeManagedSkillDir(dir, skillMd, options) {
|
|
|
14187
14377
|
if (dirExists && managed && hasSkillMd && !options.force && isPointerSkillMd(skillMd)) {
|
|
14188
14378
|
let existingIsStub = false;
|
|
14189
14379
|
try {
|
|
14190
|
-
existingIsStub = isPointerSkillMd(
|
|
14380
|
+
existingIsStub = isPointerSkillMd(readFileSync13(skillMdPath, "utf-8"));
|
|
14191
14381
|
} catch {
|
|
14192
14382
|
existingIsStub = false;
|
|
14193
14383
|
}
|
|
@@ -14267,7 +14457,7 @@ function sourceSkillMd(skillPath, name, description, kind, preferBundledDocs = f
|
|
|
14267
14457
|
if (kind === undefined || kind === "instruction" || preferBundledDocs) {
|
|
14268
14458
|
const skillMdPath = join17(skillPath, "SKILL.md");
|
|
14269
14459
|
if (existsSync9(skillMdPath))
|
|
14270
|
-
return
|
|
14460
|
+
return readFileSync13(skillMdPath, "utf-8");
|
|
14271
14461
|
}
|
|
14272
14462
|
return pointerSkillMd(name, description);
|
|
14273
14463
|
}
|
|
@@ -14307,7 +14497,7 @@ function resolveSkillAlias(name) {
|
|
|
14307
14497
|
}
|
|
14308
14498
|
|
|
14309
14499
|
// src/lib/project-state.ts
|
|
14310
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as
|
|
14500
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync14, writeFileSync as writeFileSync6 } from "fs";
|
|
14311
14501
|
import { join as join18 } from "path";
|
|
14312
14502
|
var VALID_PIN_SOURCES = [
|
|
14313
14503
|
"official",
|
|
@@ -14333,7 +14523,7 @@ function loadProjectConfig(targetDir = process.cwd()) {
|
|
|
14333
14523
|
if (!existsSync10(path))
|
|
14334
14524
|
return null;
|
|
14335
14525
|
try {
|
|
14336
|
-
return normalizeProjectConfig(JSON.parse(
|
|
14526
|
+
return normalizeProjectConfig(JSON.parse(readFileSync14(path, "utf-8")));
|
|
14337
14527
|
} catch {
|
|
14338
14528
|
return null;
|
|
14339
14529
|
}
|
|
@@ -14520,7 +14710,7 @@ function createLocalSkillManifest(name, generateSkillMd) {
|
|
|
14520
14710
|
let skillMd = "";
|
|
14521
14711
|
const skillMdPath = join19(sourcePath, "SKILL.md");
|
|
14522
14712
|
if (existsSync11(skillMdPath)) {
|
|
14523
|
-
skillMd =
|
|
14713
|
+
skillMd = readFileSync15(skillMdPath, "utf-8");
|
|
14524
14714
|
} else if (generateSkillMd) {
|
|
14525
14715
|
skillMd = generateSkillMd(name) ?? "";
|
|
14526
14716
|
} else {
|
|
@@ -14639,7 +14829,7 @@ function resolveAgentSkillMd(name, generateSkillMd) {
|
|
|
14639
14829
|
const sourcePath = getSkillPath(name);
|
|
14640
14830
|
const skillMdPath = join19(sourcePath, "SKILL.md");
|
|
14641
14831
|
if (existsSync11(skillMdPath))
|
|
14642
|
-
return
|
|
14832
|
+
return readFileSync15(skillMdPath, "utf-8");
|
|
14643
14833
|
if (generateSkillMd)
|
|
14644
14834
|
return generateSkillMd(name);
|
|
14645
14835
|
return generateMinimalSkillMd(name);
|
|
@@ -14695,14 +14885,14 @@ function readBundledSkillVersion(name) {
|
|
|
14695
14885
|
if (!existsSync11(pkgPath))
|
|
14696
14886
|
return "unknown";
|
|
14697
14887
|
try {
|
|
14698
|
-
const pkg = JSON.parse(
|
|
14888
|
+
const pkg = JSON.parse(readFileSync15(pkgPath, "utf-8"));
|
|
14699
14889
|
return pkg.version || "unknown";
|
|
14700
14890
|
} catch {
|
|
14701
14891
|
return "unknown";
|
|
14702
14892
|
}
|
|
14703
14893
|
}
|
|
14704
14894
|
function readFileIfExists(path) {
|
|
14705
|
-
return existsSync11(path) ?
|
|
14895
|
+
return existsSync11(path) ? readFileSync15(path, "utf-8") : null;
|
|
14706
14896
|
}
|
|
14707
14897
|
function loadProjectConfigCompat(targetDir) {
|
|
14708
14898
|
return loadProjectConfig(targetDir);
|
|
@@ -14750,7 +14940,7 @@ function isInstructionSkillDir(skillPath, meta) {
|
|
|
14750
14940
|
if (!existsSync12(skillMdPath))
|
|
14751
14941
|
return false;
|
|
14752
14942
|
try {
|
|
14753
|
-
return parseSkillFrontmatter(
|
|
14943
|
+
return parseSkillFrontmatter(readFileSync16(skillMdPath, "utf-8"))?.kind === "instruction";
|
|
14754
14944
|
} catch {
|
|
14755
14945
|
return false;
|
|
14756
14946
|
}
|
|
@@ -14801,7 +14991,7 @@ function getSkillRequirements(name) {
|
|
|
14801
14991
|
const meta = getSkill(name);
|
|
14802
14992
|
let dependencies = {};
|
|
14803
14993
|
try {
|
|
14804
|
-
dependencies = JSON.parse(
|
|
14994
|
+
dependencies = JSON.parse(readFileSync16(join20(skillPath, "package.json"), "utf8")).dependencies || {};
|
|
14805
14995
|
} catch {}
|
|
14806
14996
|
return getSkillRequirementsFromContent(name, texts, dependencies, meta);
|
|
14807
14997
|
}
|
|
@@ -14869,7 +15059,7 @@ async function runSkill(name, args, options = {}) {
|
|
|
14869
15059
|
}
|
|
14870
15060
|
let entryPoint2;
|
|
14871
15061
|
try {
|
|
14872
|
-
const pkg = JSON.parse(
|
|
15062
|
+
const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
|
|
14873
15063
|
if (pkg.bin) {
|
|
14874
15064
|
const binValues = Object.values(pkg.bin);
|
|
14875
15065
|
entryPoint2 = binValues[0];
|
|
@@ -14972,7 +15162,7 @@ function generateSkillMd(name) {
|
|
|
14972
15162
|
const pkgPath = join20(skillPath, "package.json");
|
|
14973
15163
|
if (existsSync12(pkgPath)) {
|
|
14974
15164
|
try {
|
|
14975
|
-
const pkg = JSON.parse(
|
|
15165
|
+
const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
|
|
14976
15166
|
if (pkg.bin) {
|
|
14977
15167
|
const binKeys = Object.keys(pkg.bin);
|
|
14978
15168
|
if (binKeys.length > 0)
|
|
@@ -15048,7 +15238,7 @@ function extractEnvVars(text2) {
|
|
|
15048
15238
|
function readIfExists(path) {
|
|
15049
15239
|
try {
|
|
15050
15240
|
if (existsSync12(path)) {
|
|
15051
|
-
return
|
|
15241
|
+
return readFileSync16(path, "utf-8");
|
|
15052
15242
|
}
|
|
15053
15243
|
} catch {}
|
|
15054
15244
|
return null;
|
|
@@ -16558,7 +16748,7 @@ function read2(path, changes) {
|
|
|
16558
16748
|
return null;
|
|
16559
16749
|
if (!stat2.isFile() || stat2.size > 16 * 1024 * 1024)
|
|
16560
16750
|
throw new Error(`Unsupported or oversized native discovery input: ${path}`);
|
|
16561
|
-
return
|
|
16751
|
+
return readFileSync17(path, "utf8");
|
|
16562
16752
|
}
|
|
16563
16753
|
function projected(source, changes, budget = discoveryByteBudget()) {
|
|
16564
16754
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
|
|
@@ -17649,7 +17839,7 @@ function discoverSkillsInDir(dir, source = "custom") {
|
|
|
17649
17839
|
continue;
|
|
17650
17840
|
let content;
|
|
17651
17841
|
try {
|
|
17652
|
-
content =
|
|
17842
|
+
content = readFileSync18(skillMdPath, "utf-8");
|
|
17653
17843
|
} catch {
|
|
17654
17844
|
continue;
|
|
17655
17845
|
}
|
|
@@ -17686,7 +17876,7 @@ function findExtensionSkillPath(name) {
|
|
|
17686
17876
|
continue;
|
|
17687
17877
|
let content;
|
|
17688
17878
|
try {
|
|
17689
|
-
content =
|
|
17879
|
+
content = readFileSync18(skillMdPath, "utf-8");
|
|
17690
17880
|
} catch {
|
|
17691
17881
|
continue;
|
|
17692
17882
|
}
|
|
@@ -17751,7 +17941,7 @@ function getAllTags() {
|
|
|
17751
17941
|
}
|
|
17752
17942
|
// src/lib/run-state.ts
|
|
17753
17943
|
import { createHash as createHash17, randomBytes } from "crypto";
|
|
17754
|
-
import { existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as
|
|
17944
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync19, readdirSync as readdirSync12, statSync as statSync10, writeFileSync as writeFileSync9 } from "fs";
|
|
17755
17945
|
import { extname, join as join30, relative as relative6 } from "path";
|
|
17756
17946
|
function createSkillRun(params, targetDir = process.cwd()) {
|
|
17757
17947
|
const now = new Date;
|
|
@@ -17823,7 +18013,7 @@ function appendRunEvent(context, event, data = {}) {
|
|
|
17823
18013
|
const line = JSON.stringify({ ts: new Date().toISOString(), event, ...data }) + `
|
|
17824
18014
|
`;
|
|
17825
18015
|
const path = join30(context.runDir, "events.ndjson");
|
|
17826
|
-
const previous = existsSync15(path) ?
|
|
18016
|
+
const previous = existsSync15(path) ? readFileSync19(path, "utf-8") : "";
|
|
17827
18017
|
writeFileSync9(path, previous + line);
|
|
17828
18018
|
}
|
|
17829
18019
|
function listSkillRuns(targetDir = process.cwd(), limit = 50) {
|
|
@@ -17873,7 +18063,7 @@ function collectRunArtifacts(context) {
|
|
|
17873
18063
|
const artifacts = [];
|
|
17874
18064
|
for (const path of walkFiles(context.exportDir)) {
|
|
17875
18065
|
const stat2 = statSync10(path);
|
|
17876
|
-
const bytes =
|
|
18066
|
+
const bytes = readFileSync19(path);
|
|
17877
18067
|
artifacts.push({
|
|
17878
18068
|
path: toProjectRelative(context.targetDir, path),
|
|
17879
18069
|
mime: mimeForPath(path),
|
|
@@ -17888,7 +18078,7 @@ function readRunRecord(runDir) {
|
|
|
17888
18078
|
if (!existsSync15(path))
|
|
17889
18079
|
return null;
|
|
17890
18080
|
try {
|
|
17891
|
-
return JSON.parse(
|
|
18081
|
+
return JSON.parse(readFileSync19(path, "utf-8"));
|
|
17892
18082
|
} catch {
|
|
17893
18083
|
return null;
|
|
17894
18084
|
}
|
|
@@ -18058,7 +18248,7 @@ __export(exports_external, {
|
|
|
18058
18248
|
input: () => input,
|
|
18059
18249
|
includes: () => _includes,
|
|
18060
18250
|
httpUrl: () => httpUrl,
|
|
18061
|
-
hostname: () =>
|
|
18251
|
+
hostname: () => hostname3,
|
|
18062
18252
|
hex: () => hex2,
|
|
18063
18253
|
hash: () => hash2,
|
|
18064
18254
|
guid: () => guid2,
|
|
@@ -19844,7 +20034,7 @@ __export(exports_regexes, {
|
|
|
19844
20034
|
idnEmail: () => idnEmail,
|
|
19845
20035
|
httpProtocol: () => httpProtocol,
|
|
19846
20036
|
html5Email: () => html5Email,
|
|
19847
|
-
hostname: () =>
|
|
20037
|
+
hostname: () => hostname2,
|
|
19848
20038
|
hex: () => hex,
|
|
19849
20039
|
guid: () => guid,
|
|
19850
20040
|
extendedDuration: () => extendedDuration,
|
|
@@ -19906,7 +20096,7 @@ var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]
|
|
|
19906
20096
|
var 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])$/;
|
|
19907
20097
|
var base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;
|
|
19908
20098
|
var base64url = /^[A-Za-z0-9_-]*$/;
|
|
19909
|
-
var
|
|
20099
|
+
var 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])?)*\.?$/;
|
|
19910
20100
|
var domain = /^(?=.{1,253}$)([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,63}$/;
|
|
19911
20101
|
var httpProtocol = /^https?$/;
|
|
19912
20102
|
var e164 = /^\+[1-9]\d{6,14}$/;
|
|
@@ -20743,9 +20933,9 @@ var asciiTabOrNewline = /[\t\n\r]/g;
|
|
|
20743
20933
|
function stripTabAndNewline(value) {
|
|
20744
20934
|
return value.replace(asciiTabOrNewline, "");
|
|
20745
20935
|
}
|
|
20746
|
-
function urlHostnameOk(url,
|
|
20747
|
-
|
|
20748
|
-
return
|
|
20936
|
+
function urlHostnameOk(url, hostname3) {
|
|
20937
|
+
hostname3.lastIndex = 0;
|
|
20938
|
+
return hostname3.test(url.hostname);
|
|
20749
20939
|
}
|
|
20750
20940
|
function urlProtocolOk(url, protocol) {
|
|
20751
20941
|
protocol.lastIndex = 0;
|
|
@@ -34133,7 +34323,7 @@ __export(exports_schemas2, {
|
|
|
34133
34323
|
int: () => int,
|
|
34134
34324
|
instanceof: () => _instanceof,
|
|
34135
34325
|
httpUrl: () => httpUrl,
|
|
34136
|
-
hostname: () =>
|
|
34326
|
+
hostname: () => hostname3,
|
|
34137
34327
|
hex: () => hex2,
|
|
34138
34328
|
hash: () => hash2,
|
|
34139
34329
|
guid: () => guid2,
|
|
@@ -34843,7 +35033,7 @@ var ZodCustomStringFormat = /* @__PURE__ */ $constructor("ZodCustomStringFormat"
|
|
|
34843
35033
|
function stringFormat(format, fnOrRegex, _params = {}) {
|
|
34844
35034
|
return _stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params);
|
|
34845
35035
|
}
|
|
34846
|
-
function
|
|
35036
|
+
function hostname3(_params) {
|
|
34847
35037
|
return _stringFormat(ZodCustomStringFormat, "hostname", exports_regexes.hostname, _params);
|
|
34848
35038
|
}
|
|
34849
35039
|
function hex2(_params) {
|
|
@@ -39403,7 +39593,7 @@ async function createRemoteSkillsClient(env = process.env) {
|
|
|
39403
39593
|
return connection ? new RemoteSkillsClient(connection.apiKey, connection.apiOrigin) : null;
|
|
39404
39594
|
}
|
|
39405
39595
|
// src/lib/scheduler.ts
|
|
39406
|
-
import { existsSync as existsSync16, readFileSync as
|
|
39596
|
+
import { existsSync as existsSync16, readFileSync as readFileSync20, writeFileSync as writeFileSync10, mkdirSync as mkdirSync11 } from "fs";
|
|
39407
39597
|
import { join as join31 } from "path";
|
|
39408
39598
|
function getSchedulesPath(targetDir = process.cwd()) {
|
|
39409
39599
|
return join31(targetDir, ".skills", "schedules.json");
|
|
@@ -39412,7 +39602,7 @@ function loadSchedules(targetDir = process.cwd()) {
|
|
|
39412
39602
|
const path = getSchedulesPath(targetDir);
|
|
39413
39603
|
if (existsSync16(path)) {
|
|
39414
39604
|
try {
|
|
39415
|
-
return JSON.parse(
|
|
39605
|
+
return JSON.parse(readFileSync20(path, "utf-8"));
|
|
39416
39606
|
} catch {}
|
|
39417
39607
|
}
|
|
39418
39608
|
return { version: 1, schedules: [] };
|
|
@@ -39635,7 +39825,7 @@ function revisionIdOfRecord(record7) {
|
|
|
39635
39825
|
return revisionIdOf(record7);
|
|
39636
39826
|
}
|
|
39637
39827
|
// src/lib/pull.ts
|
|
39638
|
-
import { existsSync as existsSync17, mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, readFileSync as
|
|
39828
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, readFileSync as readFileSync21, renameSync as renameSync6, rmSync as rmSync5, writeFileSync as writeFileSync11 } from "fs";
|
|
39639
39829
|
import { dirname as dirname19, join as join32 } from "path";
|
|
39640
39830
|
|
|
39641
39831
|
// src/lib/skill-bundles.ts
|
|
@@ -39835,7 +40025,7 @@ function reconcileTombstone(slug2, corpusOptions) {
|
|
|
39835
40025
|
}
|
|
39836
40026
|
function readPullMarker(dir) {
|
|
39837
40027
|
try {
|
|
39838
|
-
return JSON.parse(
|
|
40028
|
+
return JSON.parse(readFileSync21(join32(dir, PULL_MARKER_FILE), "utf-8"));
|
|
39839
40029
|
} catch {
|
|
39840
40030
|
return null;
|
|
39841
40031
|
}
|
|
@@ -42087,7 +42277,7 @@ import { createHash as createHash21, createHmac as createHmac2 } from "crypto";
|
|
|
42087
42277
|
import {
|
|
42088
42278
|
existsSync as existsSync19,
|
|
42089
42279
|
mkdirSync as mkdirSync15,
|
|
42090
|
-
readFileSync as
|
|
42280
|
+
readFileSync as readFileSync23,
|
|
42091
42281
|
readdirSync as readdirSync13,
|
|
42092
42282
|
statSync as statSync11,
|
|
42093
42283
|
writeFileSync as writeFileSync13
|
|
@@ -42254,7 +42444,7 @@ function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
|
|
|
42254
42444
|
const files = [];
|
|
42255
42445
|
if (existsSync19(projectStateDir)) {
|
|
42256
42446
|
for (const filePath of walkFiles2(projectStateDir)) {
|
|
42257
|
-
const bytes =
|
|
42447
|
+
const bytes = readFileSync23(filePath);
|
|
42258
42448
|
const relativePath = toPosix(relative8(targetDir, filePath));
|
|
42259
42449
|
files.push({
|
|
42260
42450
|
path: relativePath,
|
|
@@ -42672,7 +42862,7 @@ import { createHash as createHash22 } from "crypto";
|
|
|
42672
42862
|
import {
|
|
42673
42863
|
copyFileSync,
|
|
42674
42864
|
mkdirSync as mkdirSync16,
|
|
42675
|
-
readFileSync as
|
|
42865
|
+
readFileSync as readFileSync25,
|
|
42676
42866
|
statSync as statSync13,
|
|
42677
42867
|
writeFileSync as writeFileSync14
|
|
42678
42868
|
} from "fs";
|
|
@@ -42843,7 +43033,7 @@ function validateStationId(stationId) {
|
|
|
42843
43033
|
}
|
|
42844
43034
|
}
|
|
42845
43035
|
function sha256File(filePath) {
|
|
42846
|
-
return createHash22("sha256").update(
|
|
43036
|
+
return createHash22("sha256").update(readFileSync25(filePath)).digest("hex");
|
|
42847
43037
|
}
|
|
42848
43038
|
function scanHome(definition, homesRoot) {
|
|
42849
43039
|
const homePath = homePathFor(definition, homesRoot);
|
|
@@ -42999,7 +43189,7 @@ import {
|
|
|
42999
43189
|
copyFileSync as copyFileSync2,
|
|
43000
43190
|
mkdirSync as mkdirSync17,
|
|
43001
43191
|
readdirSync as readdirSync15,
|
|
43002
|
-
readFileSync as
|
|
43192
|
+
readFileSync as readFileSync26,
|
|
43003
43193
|
statSync as statSync14,
|
|
43004
43194
|
writeFileSync as writeFileSync15
|
|
43005
43195
|
} from "fs";
|
|
@@ -43018,7 +43208,7 @@ function readSnapshotManifest(repoRoot, stationId) {
|
|
|
43018
43208
|
const manifestPath = join36(snapshotRoot, "sync-manifest.json");
|
|
43019
43209
|
let manifest;
|
|
43020
43210
|
try {
|
|
43021
|
-
manifest = JSON.parse(
|
|
43211
|
+
manifest = JSON.parse(readFileSync26(manifestPath, "utf8"));
|
|
43022
43212
|
} catch (error61) {
|
|
43023
43213
|
fail("MANIFEST_UNREADABLE", `cannot read snapshot manifest: ${manifestPath}: ${error61.message}`);
|
|
43024
43214
|
}
|
|
@@ -43154,7 +43344,7 @@ function planStationHydration(stationId, repoRoot) {
|
|
|
43154
43344
|
for (const copy of copies) {
|
|
43155
43345
|
let isStub = false;
|
|
43156
43346
|
try {
|
|
43157
|
-
isStub = isPointerSkillMd(
|
|
43347
|
+
isStub = isPointerSkillMd(readFileSync26(copy.fullPath, "utf8"));
|
|
43158
43348
|
} catch {
|
|
43159
43349
|
isStub = false;
|
|
43160
43350
|
}
|