@hasna/skills 0.10.75 → 0.10.76
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 +18 -1
- package/bin/index.js +533 -244
- package/bin/mcp.js +6 -1
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.js +440 -154
- package/dist/lib/agent-codex-trust.d.ts +4 -0
- package/dist/lib/agent-integration.d.ts +3 -3
- package/dist/lib/agent-sync.d.ts +6 -4
- package/dist/lib/codex-corpus-write.d.ts +47 -6
- package/dist/lib/codex-hook-rpc.d.ts +3 -0
- package/dist/lib/home-adoption.d.ts +5 -5
- package/dist/lib/installer.d.ts +5 -3
- package/dist/runtime-prerequisites.js +1 -1
- package/dist/sdk/index.js +581 -295
- 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 existsSync15, readFileSync as readFileSync27, readdirSync as
|
|
6991
|
+
import { existsSync as existsSync15, readFileSync as readFileSync27, readdirSync as readdirSync15 } from "fs";
|
|
6992
6992
|
import { join as join41 } from "path";
|
|
6993
6993
|
|
|
6994
6994
|
// src/lib/config.ts
|
|
@@ -7257,12 +7257,12 @@ function unsetConfig(key, scope = "project") {
|
|
|
7257
7257
|
// src/lib/portable-skills.ts
|
|
7258
7258
|
import {
|
|
7259
7259
|
existsSync as existsSync14,
|
|
7260
|
-
mkdirSync as
|
|
7261
|
-
mkdtempSync as
|
|
7262
|
-
readdirSync as
|
|
7260
|
+
mkdirSync as mkdirSync12,
|
|
7261
|
+
mkdtempSync as mkdtempSync3,
|
|
7262
|
+
readdirSync as readdirSync14,
|
|
7263
7263
|
realpathSync as realpathSync15,
|
|
7264
7264
|
renameSync as renameSync6,
|
|
7265
|
-
rmSync as
|
|
7265
|
+
rmSync as rmSync5,
|
|
7266
7266
|
statSync as statSync13,
|
|
7267
7267
|
writeFileSync as writeFileSync9
|
|
7268
7268
|
} from "fs";
|
|
@@ -9973,7 +9973,7 @@ function assertAgentPolicyCollections(policy) {
|
|
|
9973
9973
|
|
|
9974
9974
|
// src/lib/agent-discovery.ts
|
|
9975
9975
|
import { createHash as createHash30 } from "crypto";
|
|
9976
|
-
import { lstatSync as lstatSync32, readFileSync as readFileSync26, readdirSync as
|
|
9976
|
+
import { lstatSync as lstatSync32, readFileSync as readFileSync26, readdirSync as readdirSync13, realpathSync as realpathSync13 } from "fs";
|
|
9977
9977
|
import { basename as basename15, dirname as dirname26, isAbsolute as isAbsolute28, join as join38, relative as relative10, resolve as resolve27, sep as sep15 } from "path";
|
|
9978
9978
|
import { isDeepStrictEqual as isDeepStrictEqual9 } from "util";
|
|
9979
9979
|
|
|
@@ -13491,14 +13491,14 @@ function hashDiscoveryPathFile(path, budget2, changes) {
|
|
|
13491
13491
|
}
|
|
13492
13492
|
|
|
13493
13493
|
// src/lib/codex-vendor-refresh.ts
|
|
13494
|
-
import { lstatSync as lstatSync15, readdirSync as
|
|
13494
|
+
import { lstatSync as lstatSync15, readdirSync as readdirSync7, readFileSync as readFileSync12 } from "fs";
|
|
13495
13495
|
import { isAbsolute as isAbsolute16, join as join19, relative as relative6, resolve as resolve16, sep as sep9 } from "path";
|
|
13496
13496
|
import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
|
|
13497
13497
|
|
|
13498
13498
|
// src/lib/codex-plugin-skill-controls.ts
|
|
13499
13499
|
import { createHash as createHash18 } from "crypto";
|
|
13500
13500
|
import { basename as basename8, dirname as dirname15, join as join18, relative as relative5, resolve as resolve15, sep as sep8 } from "path";
|
|
13501
|
-
import { lstatSync as lstatSync14, readdirSync as
|
|
13501
|
+
import { lstatSync as lstatSync14, readdirSync as readdirSync6, readFileSync as readFileSync11, readlinkSync as readlinkSync3, realpathSync as realpathSync6 } from "fs";
|
|
13502
13502
|
|
|
13503
13503
|
// src/lib/codex-native-skill-catalog.ts
|
|
13504
13504
|
import { realpathSync as realpathSync5 } from "fs";
|
|
@@ -13836,14 +13836,35 @@ class KernelLock {
|
|
|
13836
13836
|
}
|
|
13837
13837
|
|
|
13838
13838
|
// src/lib/codex-corpus-write.ts
|
|
13839
|
-
import {
|
|
13839
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
13840
|
+
import { execFileSync, spawnSync as spawnSync3 } from "child_process";
|
|
13840
13841
|
import { createHash as createHash17 } from "crypto";
|
|
13841
|
-
import { accessSync, constants as constants8, lstatSync as lstatSync13, readFileSync as readFileSync10, realpathSync as realpathSync3, statSync as statSync7 } from "fs";
|
|
13842
|
+
import { accessSync, constants as constants8, lstatSync as lstatSync13, mkdirSync as mkdirSync5, mkdtempSync, readdirSync as readdirSync5, readFileSync as readFileSync10, realpathSync as realpathSync3, rmSync as rmSync2, statSync as statSync7 } from "fs";
|
|
13842
13843
|
import { basename as basename7, delimiter, dirname as dirname14, isAbsolute as isAbsolute13, join as join16, relative as relative4, resolve as resolve14, sep as sep7 } from "path";
|
|
13843
13844
|
var KEY = ".native-corpus-admission";
|
|
13844
|
-
var fail = () => {
|
|
13845
|
-
throw new Error(
|
|
13845
|
+
var fail = (reason2) => {
|
|
13846
|
+
throw new Error(`CODEX_CORPUS_ADMISSION_REQUIRED: verified native admission and its existing shared lock are required${reason2 ? ` (${reason2})` : ""}`);
|
|
13846
13847
|
};
|
|
13848
|
+
function codexAdmissionRecord(options) {
|
|
13849
|
+
const record4 = options.onCodexAdmission;
|
|
13850
|
+
const invalid = () => {
|
|
13851
|
+
throw new Error("CODEX_CORPUS_ADMISSION_RECORD_INVALID: onCodexAdmission must be a synchronous function");
|
|
13852
|
+
};
|
|
13853
|
+
if (record4 !== undefined && typeof record4 !== "function")
|
|
13854
|
+
invalid();
|
|
13855
|
+
return { policy: { fallback: typeof record4 === "function" }, deliver(admission) {
|
|
13856
|
+
if (!admission || typeof record4 !== "function")
|
|
13857
|
+
return;
|
|
13858
|
+
const result = record4(admission);
|
|
13859
|
+
if (result !== null && (typeof result === "object" || typeof result === "function") && typeof result.then === "function") {
|
|
13860
|
+
Promise.resolve(result).catch(() => {});
|
|
13861
|
+
invalid();
|
|
13862
|
+
}
|
|
13863
|
+
} };
|
|
13864
|
+
}
|
|
13865
|
+
function codexAdmissionReceipt(admission) {
|
|
13866
|
+
return admission?.nativeAdmission === "unavailable" && admission.probe ? { nativeAdmission: "unavailable", nativeAdmissionProbe: { ...admission.probe } } : {};
|
|
13867
|
+
}
|
|
13847
13868
|
function physicalTarget(path) {
|
|
13848
13869
|
const suffix = [];
|
|
13849
13870
|
for (let cursor = path;; cursor = dirname14(cursor)) {
|
|
@@ -13925,13 +13946,246 @@ function executable(options) {
|
|
|
13925
13946
|
const digest = hash2();
|
|
13926
13947
|
if (options.codexSha256 && digest !== options.codexSha256)
|
|
13927
13948
|
return fail();
|
|
13928
|
-
return { path, assertCurrent() {
|
|
13949
|
+
return { path, sha256: digest, size: Number(initial.size), assertCurrent() {
|
|
13929
13950
|
const current = statSync7(path, { bigint: true });
|
|
13930
13951
|
if (realpathSync3(found) !== path || ["dev", "ino", "size", "mtimeNs", "ctimeNs", "mode"].some((key2) => initial[key2] !== current[key2]) || hash2() !== digest)
|
|
13931
13952
|
fail();
|
|
13932
13953
|
} };
|
|
13933
13954
|
}
|
|
13934
|
-
|
|
13955
|
+
var PROBE = { timeout: 5000, maxBuffer: 4096, killSignal: "SIGKILL", encoding: "utf8" };
|
|
13956
|
+
var UNRECOGNIZED = /^error: unrecognized subcommand 'corpus-admission-inspect'(?:\r?\n|$)/;
|
|
13957
|
+
var VERSION = /^codex-cli (?:0|[1-9][0-9]{0,5})\.(?:0|[1-9][0-9]{0,5})\.(?:0|[1-9][0-9]{0,5})(?:-[0-9A-Za-z-]{1,32}(?:\.[0-9A-Za-z-]{1,32}){0,7})?$/;
|
|
13958
|
+
var LOCK_DIRECTORY = "codex-corpus-locks";
|
|
13959
|
+
var PROBE_PARENT = "codex-probe-homes";
|
|
13960
|
+
var retain = (hold) => {
|
|
13961
|
+
hold.refs++;
|
|
13962
|
+
return { hold, released: false };
|
|
13963
|
+
};
|
|
13964
|
+
var release = (ref) => {
|
|
13965
|
+
if (ref.released)
|
|
13966
|
+
return;
|
|
13967
|
+
ref.released = true;
|
|
13968
|
+
if (--ref.hold.refs === 0)
|
|
13969
|
+
ref.hold.lock.close();
|
|
13970
|
+
};
|
|
13971
|
+
var enclosing = new AsyncLocalStorage;
|
|
13972
|
+
var leaseHolds = new WeakMap;
|
|
13973
|
+
var contains = (base, path) => {
|
|
13974
|
+
const distance = relative4(base, path);
|
|
13975
|
+
return distance === "" || !distance.startsWith(`..${sep7}`) && distance !== ".." && !isAbsolute13(distance);
|
|
13976
|
+
};
|
|
13977
|
+
function nativeLockAbsent(root) {
|
|
13978
|
+
for (const name of [`${KEY}.flock-v1`, `${KEY}.lock`]) {
|
|
13979
|
+
try {
|
|
13980
|
+
lstatSync13(join16(root, name));
|
|
13981
|
+
return false;
|
|
13982
|
+
} catch (error) {
|
|
13983
|
+
if (error.code !== "ENOENT")
|
|
13984
|
+
throw error;
|
|
13985
|
+
}
|
|
13986
|
+
}
|
|
13987
|
+
return true;
|
|
13988
|
+
}
|
|
13989
|
+
function skillsState(root, leaf, roots) {
|
|
13990
|
+
const chain = [realpathSync3(dirname14(root))];
|
|
13991
|
+
for (const part of [".hasna", "skills", leaf])
|
|
13992
|
+
chain.push(join16(chain.at(-1), part));
|
|
13993
|
+
const path = chain.at(-1);
|
|
13994
|
+
const uid2 = process.getuid();
|
|
13995
|
+
const verify = () => {
|
|
13996
|
+
if (roots.some((item) => contains(item, path)) || codexCorpusRootForPath(path) !== undefined)
|
|
13997
|
+
fail();
|
|
13998
|
+
for (let ancestor = dirname14(chain[0]);; ancestor = dirname14(ancestor)) {
|
|
13999
|
+
const stat2 = lstatSync13(ancestor), sticky = stat2.uid === 0 && (stat2.mode & 512) !== 0;
|
|
14000
|
+
if (!stat2.isDirectory() || stat2.uid !== uid2 && stat2.uid !== 0 || (stat2.mode & 18) !== 0 && !sticky)
|
|
14001
|
+
fail();
|
|
14002
|
+
if (dirname14(ancestor) === ancestor)
|
|
14003
|
+
break;
|
|
14004
|
+
}
|
|
14005
|
+
for (const component of chain) {
|
|
14006
|
+
const stat2 = lstatSync13(component, { throwIfNoEntry: false });
|
|
14007
|
+
if (!stat2)
|
|
14008
|
+
return;
|
|
14009
|
+
if (!stat2.isDirectory() || stat2.uid !== uid2 && stat2.uid !== 0 || (stat2.mode & 18) !== 0 || component === path && stat2.uid !== uid2)
|
|
14010
|
+
fail();
|
|
14011
|
+
}
|
|
14012
|
+
};
|
|
14013
|
+
verify();
|
|
14014
|
+
return { path, ensure() {
|
|
14015
|
+
verify();
|
|
14016
|
+
for (const component of chain.slice(1)) {
|
|
14017
|
+
try {
|
|
14018
|
+
mkdirSync5(component, { mode: 448 });
|
|
14019
|
+
} catch (error) {
|
|
14020
|
+
if (error.code !== "EEXIST")
|
|
14021
|
+
throw error;
|
|
14022
|
+
}
|
|
14023
|
+
}
|
|
14024
|
+
verify();
|
|
14025
|
+
if (realpathSync3(path) !== path)
|
|
14026
|
+
fail();
|
|
14027
|
+
return path;
|
|
14028
|
+
} };
|
|
14029
|
+
}
|
|
14030
|
+
function probeParent(roots) {
|
|
14031
|
+
const dataRoot = resolve14(getDataDirReadOnly()), path = join16(dataRoot, PROBE_PARENT), uid2 = process.getuid();
|
|
14032
|
+
const chain = [];
|
|
14033
|
+
for (let component = path;; component = dirname14(component)) {
|
|
14034
|
+
chain.unshift(component);
|
|
14035
|
+
if (dirname14(component) === component)
|
|
14036
|
+
break;
|
|
14037
|
+
}
|
|
14038
|
+
const verify = () => {
|
|
14039
|
+
if (roots.some((item) => contains(item, path)) || codexCorpusRootForPath(path) !== undefined)
|
|
14040
|
+
fail();
|
|
14041
|
+
for (const component of chain) {
|
|
14042
|
+
const stat2 = lstatSync13(component, { throwIfNoEntry: false });
|
|
14043
|
+
if (!stat2)
|
|
14044
|
+
return;
|
|
14045
|
+
const skills = contains(dataRoot, component), sticky = !skills && stat2.uid === 0 && (stat2.mode & 512) !== 0;
|
|
14046
|
+
if (!stat2.isDirectory() || stat2.uid !== uid2 && (skills || stat2.uid !== 0) || (stat2.mode & 18) !== 0 && !sticky)
|
|
14047
|
+
fail();
|
|
14048
|
+
}
|
|
14049
|
+
};
|
|
14050
|
+
verify();
|
|
14051
|
+
for (const component of chain) {
|
|
14052
|
+
if (lstatSync13(component, { throwIfNoEntry: false }))
|
|
14053
|
+
continue;
|
|
14054
|
+
try {
|
|
14055
|
+
mkdirSync5(component, { mode: 448 });
|
|
14056
|
+
} catch (error) {
|
|
14057
|
+
if (error.code !== "EEXIST")
|
|
14058
|
+
throw error;
|
|
14059
|
+
}
|
|
14060
|
+
}
|
|
14061
|
+
verify();
|
|
14062
|
+
if (realpathSync3(path) !== path)
|
|
14063
|
+
fail();
|
|
14064
|
+
return path;
|
|
14065
|
+
}
|
|
14066
|
+
function probeHomeIntact(home, empty) {
|
|
14067
|
+
const stat2 = lstatSync13(home.path, { bigint: true, throwIfNoEntry: false });
|
|
14068
|
+
return !!stat2 && stat2.isDirectory() && stat2.dev === home.dev && stat2.ino === home.ino && stat2.uid === BigInt(process.getuid()) && (stat2.mode & 0o777n) === 0o700n && realpathSync3(home.path) === home.path && (!empty || readdirSync5(home.path).length === 0);
|
|
14069
|
+
}
|
|
14070
|
+
function removeProbeHome(home) {
|
|
14071
|
+
try {
|
|
14072
|
+
const stat2 = lstatSync13(home.path, { bigint: true });
|
|
14073
|
+
if (stat2.isDirectory() && stat2.dev === home.dev && stat2.ino === home.ino)
|
|
14074
|
+
rmSync2(home.path, { recursive: true, force: true });
|
|
14075
|
+
} catch {}
|
|
14076
|
+
}
|
|
14077
|
+
function probe(path, args, parent, stdio) {
|
|
14078
|
+
const created = mkdtempSync(join16(parent, "probe-")), stat2 = lstatSync13(created, { bigint: true });
|
|
14079
|
+
const home = { path: created, dev: stat2.dev, ino: stat2.ino };
|
|
14080
|
+
try {
|
|
14081
|
+
if (!probeHomeIntact(home, true))
|
|
14082
|
+
return;
|
|
14083
|
+
const env = { CODEX_HOME: home.path };
|
|
14084
|
+
for (const key2 of ["PATH", "HOME"])
|
|
14085
|
+
if (process.env[key2] !== undefined)
|
|
14086
|
+
env[key2] = process.env[key2];
|
|
14087
|
+
const result = spawnSync3(path, args, { ...PROBE, cwd: home.path, env, stdio: ["ignore", stdio, stdio] });
|
|
14088
|
+
return probeHomeIntact(home, false) ? result : undefined;
|
|
14089
|
+
} finally {
|
|
14090
|
+
removeProbeHome(home);
|
|
14091
|
+
}
|
|
14092
|
+
}
|
|
14093
|
+
function probeAdmissionCommand(path, parent) {
|
|
14094
|
+
const help = probe(path, ["help", "corpus-admission-inspect"], parent, "pipe");
|
|
14095
|
+
if (!help || help.error || help.signal !== null)
|
|
14096
|
+
return "inconclusive";
|
|
14097
|
+
if (help.status === 0)
|
|
14098
|
+
return "present";
|
|
14099
|
+
if (help.status !== 2 || help.stdout !== "" || typeof help.stderr !== "string" || !UNRECOGNIZED.test(help.stderr))
|
|
14100
|
+
return "inconclusive";
|
|
14101
|
+
const control = probe(path, ["help", "exec"], parent, "ignore");
|
|
14102
|
+
return control && !control.error && control.signal === null && control.status === 0 ? "absent" : "inconclusive";
|
|
14103
|
+
}
|
|
14104
|
+
function strictVersion(path, parent) {
|
|
14105
|
+
const result = probe(path, ["--version"], parent, "pipe");
|
|
14106
|
+
if (!result || result.error || result.signal !== null || result.status !== 0 || typeof result.stdout !== "string")
|
|
14107
|
+
return;
|
|
14108
|
+
const line = result.stdout.replace(/\r?\n$/, "");
|
|
14109
|
+
return VERSION.test(line) ? line : undefined;
|
|
14110
|
+
}
|
|
14111
|
+
function rootLockKey(root, id) {
|
|
14112
|
+
return `codex-corpus-${createHash17("sha256").update(`${root}\x00${id.device}\x00${id.inode}`).digest("hex")}`;
|
|
14113
|
+
}
|
|
14114
|
+
function acquireFallback(inputs, options) {
|
|
14115
|
+
let reason2 = "executable-unverified";
|
|
14116
|
+
const refs = new Map, held = [];
|
|
14117
|
+
const close = () => {
|
|
14118
|
+
for (const ref of [...refs.values()].reverse())
|
|
14119
|
+
release(ref);
|
|
14120
|
+
};
|
|
14121
|
+
try {
|
|
14122
|
+
const native = executable(options);
|
|
14123
|
+
reason2 = "skills-lock-unavailable";
|
|
14124
|
+
const roots = inputs.map((item) => item.root);
|
|
14125
|
+
const locks = new Map(roots.map((root) => [root, skillsState(root, LOCK_DIRECTORY, roots)]));
|
|
14126
|
+
const parent = probeParent(roots);
|
|
14127
|
+
reason2 = "probe-inconclusive";
|
|
14128
|
+
const state = probeAdmissionCommand(native.path, parent);
|
|
14129
|
+
if (state === "present")
|
|
14130
|
+
reason2 = "command-present";
|
|
14131
|
+
if (state !== "absent")
|
|
14132
|
+
fail();
|
|
14133
|
+
const version = strictVersion(native.path, parent);
|
|
14134
|
+
if (version === undefined)
|
|
14135
|
+
fail();
|
|
14136
|
+
reason2 = "executable-unverified";
|
|
14137
|
+
native.assertCurrent();
|
|
14138
|
+
reason2 = "skills-lock-unavailable";
|
|
14139
|
+
for (const { input, root } of inputs) {
|
|
14140
|
+
const id = identity3(root), key2 = rootLockKey(root, id);
|
|
14141
|
+
if (!refs.has(key2)) {
|
|
14142
|
+
const owner2 = enclosing.getStore()?.get(key2);
|
|
14143
|
+
if (owner2 && !owner2.released)
|
|
14144
|
+
refs.set(key2, retain(owner2.hold));
|
|
14145
|
+
else {
|
|
14146
|
+
const lock = new KernelLock(locks.get(root).ensure(), key2, { mode: "exclusive" });
|
|
14147
|
+
refs.set(key2, retain({ lock, refs: 0 }));
|
|
14148
|
+
if (!lock.trySync(1000)) {
|
|
14149
|
+
reason2 = "writer-busy";
|
|
14150
|
+
fail();
|
|
14151
|
+
}
|
|
14152
|
+
}
|
|
14153
|
+
}
|
|
14154
|
+
held.push({ input, root, id, ref: refs.get(key2) });
|
|
14155
|
+
}
|
|
14156
|
+
const assertCurrent = () => {
|
|
14157
|
+
try {
|
|
14158
|
+
for (const item of held) {
|
|
14159
|
+
if (item.ref.released)
|
|
14160
|
+
fail();
|
|
14161
|
+
item.ref.hold.lock.assertUnchanged();
|
|
14162
|
+
if (realpathSync3(item.input) !== item.root || !sameIdentity(identity3(item.root), item.id) || !nativeLockAbsent(item.root))
|
|
14163
|
+
fail();
|
|
14164
|
+
}
|
|
14165
|
+
native.assertCurrent();
|
|
14166
|
+
} catch {
|
|
14167
|
+
fail("lease-changed");
|
|
14168
|
+
}
|
|
14169
|
+
};
|
|
14170
|
+
reason2 = "lease-changed";
|
|
14171
|
+
assertCurrent();
|
|
14172
|
+
const lease = { assertCurrent, close, admission: { nativeAdmission: "unavailable", probe: {
|
|
14173
|
+
kind: "help-unrecognized-subcommand",
|
|
14174
|
+
executable: native.path,
|
|
14175
|
+
sha256: native.sha256,
|
|
14176
|
+
size: native.size,
|
|
14177
|
+
version,
|
|
14178
|
+
probeExitCode: 2,
|
|
14179
|
+
controlExitCode: 0
|
|
14180
|
+
} } };
|
|
14181
|
+
leaseHolds.set(lease, refs);
|
|
14182
|
+
return lease;
|
|
14183
|
+
} catch {
|
|
14184
|
+
close();
|
|
14185
|
+
return fail(reason2);
|
|
14186
|
+
}
|
|
14187
|
+
}
|
|
14188
|
+
function acquireCodexCorpusWrite(roots, options, policy = {}) {
|
|
13935
14189
|
const held = [];
|
|
13936
14190
|
const close = () => {
|
|
13937
14191
|
for (const item of held.reverse())
|
|
@@ -13944,10 +14198,20 @@ function acquireCodexCorpusWrite(roots, options) {
|
|
|
13944
14198
|
fail();
|
|
13945
14199
|
}
|
|
13946
14200
|
};
|
|
14201
|
+
let fallback = false, refusal;
|
|
13947
14202
|
try {
|
|
13948
14203
|
if (roots.some((root) => typeof root !== "string" || !isAbsolute13(root) || root.includes("\x00")))
|
|
13949
14204
|
fail();
|
|
13950
14205
|
const inputs = [...new Set(roots)].map((input) => ({ input, root: realpathSync3(input) })).sort((a, b) => a.root.localeCompare(b.root));
|
|
14206
|
+
const absent = inputs.filter(({ root }) => nativeLockAbsent(root));
|
|
14207
|
+
if (absent.length && absent.length !== inputs.length) {
|
|
14208
|
+
refusal = "native-lock-present";
|
|
14209
|
+
fail();
|
|
14210
|
+
}
|
|
14211
|
+
if (absent.length && policy.fallback !== false) {
|
|
14212
|
+
fallback = true;
|
|
14213
|
+
return acquireFallback(inputs, options);
|
|
14214
|
+
}
|
|
13951
14215
|
for (const { input, root } of inputs) {
|
|
13952
14216
|
const lock = new KernelLock(root, KEY, { mode: "shared", existingOnly: true });
|
|
13953
14217
|
held.push({ input, root, lock });
|
|
@@ -13975,19 +14239,25 @@ function acquireCodexCorpusWrite(roots, options) {
|
|
|
13975
14239
|
if (Object.keys(row).sort().join(",") !== "lock,root,schema,state" || row.schema !== "codex-corpus-admission-status/v1" || row.state !== "committed-v1" && row.state !== "committed-v2" || !sameIdentity(row.root, rootIdentity) || !sameIdentity(row.lock, lockIdentity))
|
|
13976
14240
|
fail();
|
|
13977
14241
|
}
|
|
13978
|
-
return { assertCurrent, close };
|
|
13979
|
-
} catch {
|
|
14242
|
+
return { assertCurrent, close, admission: { nativeAdmission: "verified" } };
|
|
14243
|
+
} catch (error) {
|
|
14244
|
+
if (fallback)
|
|
14245
|
+
throw error;
|
|
13980
14246
|
close();
|
|
13981
|
-
return fail();
|
|
14247
|
+
return fail(refusal);
|
|
13982
14248
|
}
|
|
13983
14249
|
}
|
|
13984
|
-
function
|
|
14250
|
+
function scoped(lease, run) {
|
|
14251
|
+
const holds = leaseHolds.get(lease);
|
|
14252
|
+
return holds?.size ? enclosing.run(new Map([...enclosing.getStore() ?? [], ...holds]), run) : run();
|
|
14253
|
+
}
|
|
14254
|
+
function withCodexCorpusWrite(roots, run, options = {}, policy = {}) {
|
|
13985
14255
|
if (!roots.length)
|
|
13986
14256
|
return run(() => {});
|
|
13987
|
-
const lease = acquireCodexCorpusWrite(roots, options);
|
|
14257
|
+
const lease = acquireCodexCorpusWrite(roots, options, policy);
|
|
13988
14258
|
try {
|
|
13989
14259
|
lease.assertCurrent();
|
|
13990
|
-
const result = run(lease.assertCurrent);
|
|
14260
|
+
const result = scoped(lease, () => run(lease.assertCurrent, lease.admission));
|
|
13991
14261
|
lease.assertCurrent();
|
|
13992
14262
|
return result;
|
|
13993
14263
|
} finally {
|
|
@@ -14108,6 +14378,7 @@ async function connectCodexHookRpc(options) {
|
|
|
14108
14378
|
const rpc = {
|
|
14109
14379
|
version,
|
|
14110
14380
|
processId: child2.pid,
|
|
14381
|
+
admission: corpusLease.admission,
|
|
14111
14382
|
request(method, params) {
|
|
14112
14383
|
if (stopped)
|
|
14113
14384
|
return Promise.reject(new Error(configInvalid ? CODEX_CONFIG_INVALID : "CODEX_HOOK_TRUST_NATIVE_RPC_CLOSED"));
|
|
@@ -14561,7 +14832,7 @@ function reviewedRetiredCodexRoot(cache, root, controls, rules, read2, allowAbse
|
|
|
14561
14832
|
if (!enrolled.some((control) => control.namespace === parsed.namespace && control.manifestSha256 === parsed.manifestSha256 && !parsed.appSha256 && !parsed.mcpSha256))
|
|
14562
14833
|
return false;
|
|
14563
14834
|
let entries = 0;
|
|
14564
|
-
const emptySkills = (directory, depth) => depth <= 64 &&
|
|
14835
|
+
const emptySkills = (directory, depth) => depth <= 64 && readdirSync6(directory).every((name) => {
|
|
14565
14836
|
if (++entries > 4096 || name === "SKILL.md")
|
|
14566
14837
|
return false;
|
|
14567
14838
|
const path = join18(directory, name), stat2 = lstatSync14(path);
|
|
@@ -14586,7 +14857,7 @@ function reviewedCodexPluginCapabilitiesUnchanged(cache, controls, read2, rules)
|
|
|
14586
14857
|
if (control.remotePluginId !== undefined && !remoteInstallationMatches(parent, control.remotePluginId, read2))
|
|
14587
14858
|
return false;
|
|
14588
14859
|
}
|
|
14589
|
-
const names =
|
|
14860
|
+
const names = readdirSync6(parent);
|
|
14590
14861
|
entries += names.length;
|
|
14591
14862
|
if (entries > 4096)
|
|
14592
14863
|
return false;
|
|
@@ -14803,11 +15074,11 @@ var MAX_SUBTREE_DEPTH = 32;
|
|
|
14803
15074
|
var hiddenName = (name) => name.startsWith(".") || name === "node_modules";
|
|
14804
15075
|
var isSkillDocument = (name) => name.toLowerCase() === "skill.md";
|
|
14805
15076
|
var present = (path) => lstatSync15(path, { throwIfNoEntry: false }) !== undefined;
|
|
14806
|
-
var holdsOtherControl = (path) =>
|
|
15077
|
+
var holdsOtherControl = (path) => readdirSync7(path).some((name) => OTHER_PLUGIN_CONTROLS.includes(name.toLowerCase()));
|
|
14807
15078
|
function pluginTreeVisible(path, hidden, insideSkill, depth, budget2) {
|
|
14808
15079
|
if (depth > MAX_SUBTREE_DEPTH)
|
|
14809
15080
|
return false;
|
|
14810
|
-
const names =
|
|
15081
|
+
const names = readdirSync7(path);
|
|
14811
15082
|
const skill = names.some(isSkillDocument);
|
|
14812
15083
|
if (skill && (hidden || insideSkill))
|
|
14813
15084
|
return false;
|
|
@@ -14831,7 +15102,7 @@ function codexVendorPluginRootRefreshSafe(root, budget2 = { remaining: MAX_SUBTR
|
|
|
14831
15102
|
return false;
|
|
14832
15103
|
if (!directory(join19(root, ".codex-plugin")))
|
|
14833
15104
|
return false;
|
|
14834
|
-
const controls =
|
|
15105
|
+
const controls = readdirSync7(join19(root, ".codex-plugin"));
|
|
14835
15106
|
if (controls.length !== 1 || controls[0] !== "plugin.json")
|
|
14836
15107
|
return false;
|
|
14837
15108
|
const manifest = join19(root, ".codex-plugin", "plugin.json"), stat2 = lstatSync15(manifest, { throwIfNoEntry: false });
|
|
@@ -14854,7 +15125,7 @@ function codexVendorPluginRootRefreshSafe(root, budget2 = { remaining: MAX_SUBTR
|
|
|
14854
15125
|
}
|
|
14855
15126
|
function vendorMembers(path, budget2) {
|
|
14856
15127
|
const directories = [];
|
|
14857
|
-
for (const name of
|
|
15128
|
+
for (const name of readdirSync7(path)) {
|
|
14858
15129
|
if (--budget2.remaining < 0)
|
|
14859
15130
|
return null;
|
|
14860
15131
|
const stat2 = lstatSync15(join19(path, name));
|
|
@@ -15144,7 +15415,7 @@ import { basename as basename13, dirname as dirname24, isAbsolute as isAbsolute2
|
|
|
15144
15415
|
import { homedir as homedir5 } from "os";
|
|
15145
15416
|
import { isAbsolute as isAbsolute25, join as join36, resolve as resolve24 } from "path";
|
|
15146
15417
|
// package.json
|
|
15147
|
-
var version = "0.10.
|
|
15418
|
+
var version = "0.10.76";
|
|
15148
15419
|
var package_default = {
|
|
15149
15420
|
name: "@hasna/skills",
|
|
15150
15421
|
version,
|
|
@@ -15287,7 +15558,7 @@ var package_default = {
|
|
|
15287
15558
|
|
|
15288
15559
|
// node_modules/@hasna/contracts/dist/client/transport.js
|
|
15289
15560
|
import { isIP } from "net";
|
|
15290
|
-
import { spawnSync as
|
|
15561
|
+
import { spawnSync as spawnSync4 } from "child_process";
|
|
15291
15562
|
import { closeSync as closeSync22, fstatSync as fstatSync22, openSync as openSync22, readFileSync as readFileSync22 } from "fs";
|
|
15292
15563
|
import { O_NOFOLLOW as O_NOFOLLOW2, O_NONBLOCK as O_NONBLOCK2, O_RDONLY as O_RDONLY2 } from "constants";
|
|
15293
15564
|
import { hostname as osHostname } from "os";
|
|
@@ -15687,7 +15958,7 @@ function isAmbientEnvironment(env) {
|
|
|
15687
15958
|
return env === process.env || env[AMBIENT_ENVIRONMENT] === true;
|
|
15688
15959
|
}
|
|
15689
15960
|
function defaultKeychainRunner(argv) {
|
|
15690
|
-
const result =
|
|
15961
|
+
const result = spawnSync4(KEYCHAIN_SECURITY_BIN, [...argv], {
|
|
15691
15962
|
encoding: "utf8",
|
|
15692
15963
|
stdio: ["ignore", "pipe", "pipe"],
|
|
15693
15964
|
timeout: KEYCHAIN_SPAWN_TIMEOUT_MS
|
|
@@ -16782,7 +17053,7 @@ async function createProfileClient(signal) {
|
|
|
16782
17053
|
}
|
|
16783
17054
|
|
|
16784
17055
|
// src/lib/dependency-preparation.ts
|
|
16785
|
-
import { constants as constants10, closeSync as closeSync10, fstatSync as fstatSync10, lstatSync as lstatSync18, mkdirSync as
|
|
17056
|
+
import { constants as constants10, closeSync as closeSync10, fstatSync as fstatSync10, lstatSync as lstatSync18, mkdirSync as mkdirSync6, openSync as openSync10, readFileSync as readFileSync14, readdirSync as readdirSync8, rmdirSync as rmdirSync2, unlinkSync as unlinkSync3, ftruncateSync, writeSync as writeSync2 } from "fs";
|
|
16786
17057
|
import { join as join21 } from "path";
|
|
16787
17058
|
|
|
16788
17059
|
// src/lib/preparation-process.ts
|
|
@@ -16841,7 +17112,7 @@ function claimPreparation(skillPath) {
|
|
|
16841
17112
|
const state = join21(marker, "state.json"), active = join21(marker, "active");
|
|
16842
17113
|
let created = false;
|
|
16843
17114
|
try {
|
|
16844
|
-
|
|
17115
|
+
mkdirSync6(marker, { mode: 448 });
|
|
16845
17116
|
created = true;
|
|
16846
17117
|
} catch (error) {
|
|
16847
17118
|
if (error.code !== "EEXIST")
|
|
@@ -16852,7 +17123,7 @@ function claimPreparation(skillPath) {
|
|
|
16852
17123
|
if (!lstatSync18(marker).isDirectory() || lstatSync18(marker).isSymbolicLink())
|
|
16853
17124
|
return;
|
|
16854
17125
|
if (!created) {
|
|
16855
|
-
if (
|
|
17126
|
+
if (readdirSync8(marker).some((name) => name !== "state.json"))
|
|
16856
17127
|
return;
|
|
16857
17128
|
if (!lstatSync18(state).isFile() || lstatSync18(state).isSymbolicLink() || lstatSync18(state).size > 1024)
|
|
16858
17129
|
return;
|
|
@@ -16860,7 +17131,7 @@ function claimPreparation(skillPath) {
|
|
|
16860
17131
|
if (previous.version !== 1 || previous.status !== "failed" || Object.keys(previous).length !== 2)
|
|
16861
17132
|
return;
|
|
16862
17133
|
}
|
|
16863
|
-
|
|
17134
|
+
mkdirSync6(active, { mode: 448 });
|
|
16864
17135
|
fd = openSync10(state, constants10.O_RDWR | constants10.O_NOFOLLOW | (created ? constants10.O_CREAT | constants10.O_EXCL : 0), 384);
|
|
16865
17136
|
if (!fstatSync10(fd).isFile()) {
|
|
16866
17137
|
closeSync10(fd);
|
|
@@ -16993,7 +17264,7 @@ import { existsSync as existsSync13, readFileSync as readFileSync25 } from "fs";
|
|
|
16993
17264
|
import { join as join35 } from "path";
|
|
16994
17265
|
|
|
16995
17266
|
// src/lib/installer.ts
|
|
16996
|
-
import { existsSync as existsSync12, readFileSync as readFileSync23, rmSync as
|
|
17267
|
+
import { existsSync as existsSync12, readFileSync as readFileSync23, rmSync as rmSync4 } from "fs";
|
|
16997
17268
|
import { join as join34 } from "path";
|
|
16998
17269
|
import { homedir as homedir4 } from "os";
|
|
16999
17270
|
|
|
@@ -17002,12 +17273,12 @@ import {
|
|
|
17002
17273
|
cpSync as cpSync2,
|
|
17003
17274
|
existsSync as existsSync10,
|
|
17004
17275
|
lstatSync as lstatSync29,
|
|
17005
|
-
mkdirSync as
|
|
17006
|
-
mkdtempSync,
|
|
17276
|
+
mkdirSync as mkdirSync10,
|
|
17277
|
+
mkdtempSync as mkdtempSync2,
|
|
17007
17278
|
readFileSync as readFileSync20,
|
|
17008
|
-
readdirSync as
|
|
17279
|
+
readdirSync as readdirSync12,
|
|
17009
17280
|
renameSync as renameSync5,
|
|
17010
|
-
rmSync as
|
|
17281
|
+
rmSync as rmSync3,
|
|
17011
17282
|
statSync as statSync12,
|
|
17012
17283
|
writeFileSync as writeFileSync7
|
|
17013
17284
|
} from "fs";
|
|
@@ -17016,7 +17287,7 @@ import { basename as basename12, dirname as dirname23, join as join32 } from "pa
|
|
|
17016
17287
|
|
|
17017
17288
|
// src/lib/codex-native-skill-policy.ts
|
|
17018
17289
|
import { createHash as createHash21, randomUUID as randomUUID3 } from "crypto";
|
|
17019
|
-
import { closeSync as closeSync11, constants as constants11, fstatSync as fstatSync11, fsyncSync as fsyncSync3, lstatSync as lstatSync19, mkdirSync as
|
|
17290
|
+
import { closeSync as closeSync11, constants as constants11, fstatSync as fstatSync11, fsyncSync as fsyncSync3, lstatSync as lstatSync19, mkdirSync as mkdirSync7, openSync as openSync11, readFileSync as readFileSync15, readSync as readSync7, readlinkSync as readlinkSync4, realpathSync as realpathSync8, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
17020
17291
|
import { dirname as dirname17, isAbsolute as isAbsolute18, join as join23, resolve as resolve17 } from "path";
|
|
17021
17292
|
import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
|
|
17022
17293
|
var CODEX_NATIVE_POLICY_CAPABILITY = "host-path-allowlist-v1";
|
|
@@ -17285,7 +17556,7 @@ function writeExecutableCache(dataDir2, entries) {
|
|
|
17285
17556
|
return;
|
|
17286
17557
|
const existing = lstatSync19(directory2, { throwIfNoEntry: false });
|
|
17287
17558
|
if (!existing)
|
|
17288
|
-
|
|
17559
|
+
mkdirSync7(directory2, { mode: 448 });
|
|
17289
17560
|
else if (existing.isSymbolicLink() || !existing.isDirectory())
|
|
17290
17561
|
return;
|
|
17291
17562
|
const holder = lstatSync19(directory2, { throwIfNoEntry: false, bigint: true });
|
|
@@ -17580,7 +17851,7 @@ function recordCodexNativePolicyAcceptance(dataDir2, verification, accepted) {
|
|
|
17580
17851
|
...verification.attestation ? { attestation: { schema: verification.attestation.schema, peerProcessId: verification.attestation.peerProcessId } } : {}
|
|
17581
17852
|
};
|
|
17582
17853
|
try {
|
|
17583
|
-
|
|
17854
|
+
mkdirSync7(directory2, { recursive: true, mode: 448 });
|
|
17584
17855
|
const stat2 = lstatSync19(directory2);
|
|
17585
17856
|
if (stat2.isSymbolicLink() || !stat2.isDirectory())
|
|
17586
17857
|
throw new Error(`the receipt directory is not a real directory: ${directory2}`);
|
|
@@ -17612,7 +17883,7 @@ function recordCodexNativePolicyAcceptance(dataDir2, verification, accepted) {
|
|
|
17612
17883
|
|
|
17613
17884
|
// src/lib/codex-semantic-cache-witness.ts
|
|
17614
17885
|
import { createHash as createHash22 } from "crypto";
|
|
17615
|
-
import { constants as constants12, closeSync as closeSync12, fstatSync as fstatSync12, lstatSync as lstatSync20, openSync as openSync12, readSync as readSync8, readdirSync as
|
|
17886
|
+
import { constants as constants12, closeSync as closeSync12, fstatSync as fstatSync12, lstatSync as lstatSync20, openSync as openSync12, readSync as readSync8, readdirSync as readdirSync9, realpathSync as realpathSync9 } from "fs";
|
|
17616
17887
|
import { basename as basename10, dirname as dirname18, isAbsolute as isAbsolute19, join as join25, relative as relative8, resolve as resolve18, sep as sep11 } from "path";
|
|
17617
17888
|
var CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA = "hasna.codex-semantic-cache-witness.v1";
|
|
17618
17889
|
var identifier5 = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(value);
|
|
@@ -17777,7 +18048,7 @@ function assertCanonicalDirectory(path) {
|
|
|
17777
18048
|
function walkSafeTree(path, state, depth = 0, root = path) {
|
|
17778
18049
|
if (depth > 64 || ++state.entries > 16384)
|
|
17779
18050
|
refuse4();
|
|
17780
|
-
const names =
|
|
18051
|
+
const names = readdirSync9(path).sort();
|
|
17781
18052
|
const files = [];
|
|
17782
18053
|
for (const name of names) {
|
|
17783
18054
|
if (!name || name === "." || name === ".." || name.includes(sep11) || ++state.entries > 16384)
|
|
@@ -17923,7 +18194,7 @@ function appOnlyParentProjection(cacheRoot, parents2, read2) {
|
|
|
17923
18194
|
} catch {
|
|
17924
18195
|
refuse4();
|
|
17925
18196
|
}
|
|
17926
|
-
const versions =
|
|
18197
|
+
const versions = readdirSync9(parent.pluginParent).filter((name) => name !== ".codex-remote-plugin-install.json");
|
|
17927
18198
|
if (!versions.length || versions.length > 4096)
|
|
17928
18199
|
refuse4();
|
|
17929
18200
|
const materializations = versions.map((version2) => {
|
|
@@ -18068,7 +18339,7 @@ function reviewedHookParentProjection(cacheRoot, parents2, read2) {
|
|
|
18068
18339
|
if (createHash22("sha256").update(marketplaceText).digest("hex") !== parent.marketplaceSha256 || !codexLocalMarketplaceMapsPlugin(marketplaceText, parts[0], parent.namespace))
|
|
18069
18340
|
refuse4();
|
|
18070
18341
|
}
|
|
18071
|
-
const materializations =
|
|
18342
|
+
const materializations = readdirSync9(parent.pluginParent).filter((name) => name !== ".codex-remote-plugin-install.json").map((version2) => {
|
|
18072
18343
|
if (!/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(version2))
|
|
18073
18344
|
refuse4();
|
|
18074
18345
|
const root = join25(parent.pluginParent, version2), stat2 = lstatSync20(root, { throwIfNoEntry: false });
|
|
@@ -18102,14 +18373,14 @@ function assertParents(cacheRoot, controls, appOnlyParents, hookParents, files,
|
|
|
18102
18373
|
refuse4();
|
|
18103
18374
|
actual.add(join25(cacheRoot, parts[0], parts[1]));
|
|
18104
18375
|
}
|
|
18105
|
-
const actualMarkets =
|
|
18376
|
+
const actualMarkets = readdirSync9(cacheRoot);
|
|
18106
18377
|
if (actualMarkets.length !== expectedMarkets.size || actualMarkets.some((market) => !expectedMarkets.has(market)))
|
|
18107
18378
|
refuse4();
|
|
18108
18379
|
for (const market of actualMarkets) {
|
|
18109
18380
|
const marketPath = join25(cacheRoot, market), marketStat = lstatSync20(marketPath);
|
|
18110
18381
|
if (!identifier5(market) || !marketStat.isDirectory() || marketStat.isSymbolicLink())
|
|
18111
18382
|
refuse4();
|
|
18112
|
-
for (const plugin of
|
|
18383
|
+
for (const plugin of readdirSync9(marketPath)) {
|
|
18113
18384
|
const parent = join25(marketPath, plugin), stat2 = lstatSync20(parent);
|
|
18114
18385
|
if (!identifier5(plugin) || !stat2.isDirectory() || stat2.isSymbolicLink())
|
|
18115
18386
|
refuse4();
|
|
@@ -18161,7 +18432,7 @@ function assertSkillMaterializations(cacheRoot, controls, files, read2) {
|
|
|
18161
18432
|
const expectedNames = new Set(rows.map((row) => row.name));
|
|
18162
18433
|
if (expectedNames.size !== rows.length)
|
|
18163
18434
|
refuse4();
|
|
18164
|
-
const entries =
|
|
18435
|
+
const entries = readdirSync9(parent);
|
|
18165
18436
|
let roots = 0;
|
|
18166
18437
|
for (const entry of entries) {
|
|
18167
18438
|
if (entry === ".codex-remote-plugin-install.json")
|
|
@@ -18400,7 +18671,7 @@ function codexPluginCacheSkillTree(path, depth) {
|
|
|
18400
18671
|
// src/lib/agent-integration.ts
|
|
18401
18672
|
import { createHash as createHash27, randomUUID as randomUUID4 } from "crypto";
|
|
18402
18673
|
import { isDeepStrictEqual as isDeepStrictEqual8 } from "util";
|
|
18403
|
-
import { existsSync as existsSync9, lstatSync as lstatSync28, statSync as statSync11, mkdirSync as
|
|
18674
|
+
import { existsSync as existsSync9, lstatSync as lstatSync28, statSync as statSync11, mkdirSync as mkdirSync9, readFileSync as readFileSync19, readdirSync as readdirSync11, opendirSync as opendirSync4, readlinkSync as readlinkSync7, realpathSync as realpathSync12, renameSync as renameSync4, rmdirSync as rmdirSync3, writeFileSync as writeFileSync6, unlinkSync as unlinkSync5, chmodSync, openSync as openSync17, closeSync as closeSync17, fsyncSync as fsyncSync7, fstatSync as fstatSync17, readSync as readSync12, constants as constants18, linkSync as linkSync3 } from "fs";
|
|
18404
18675
|
import { basename as basename11, dirname as dirname22, join as join31, resolve as resolve23, relative as relative9, isAbsolute as isAbsolute24, sep as sep14 } from "path";
|
|
18405
18676
|
import { homedir as homedir2 } from "os";
|
|
18406
18677
|
|
|
@@ -18486,7 +18757,7 @@ function requiresCliSkillLoading(dataDir2 = getDataDirReadOnly()) {
|
|
|
18486
18757
|
|
|
18487
18758
|
// src/lib/agent-bridge.ts
|
|
18488
18759
|
import { createHash as createHash23 } from "crypto";
|
|
18489
|
-
import { lstatSync as lstatSync23, readFileSync as readFileSync17, readdirSync as
|
|
18760
|
+
import { lstatSync as lstatSync23, readFileSync as readFileSync17, readdirSync as readdirSync10 } from "fs";
|
|
18490
18761
|
import { join as join28 } from "path";
|
|
18491
18762
|
var CLI_BRIDGE_NAME = "skills-cli";
|
|
18492
18763
|
var CLI_BRIDGE_VERSION = 1;
|
|
@@ -18516,7 +18787,7 @@ function isOwnedCliBridge(path, expectedPaths) {
|
|
|
18516
18787
|
try {
|
|
18517
18788
|
if (!lstatSync23(path).isDirectory())
|
|
18518
18789
|
return false;
|
|
18519
|
-
if (JSON.stringify(
|
|
18790
|
+
if (JSON.stringify(readdirSync10(path).sort()) !== JSON.stringify(Object.keys(CLI_BRIDGE_FILES).sort()))
|
|
18520
18791
|
return false;
|
|
18521
18792
|
return Object.entries(CLI_BRIDGE_FILES).every(([name, content]) => {
|
|
18522
18793
|
const file = join28(path, name), stat2 = lstatSync23(file);
|
|
@@ -18796,7 +19067,7 @@ function disableCodexBundledSkills(text2) {
|
|
|
18796
19067
|
}
|
|
18797
19068
|
|
|
18798
19069
|
// src/lib/agent-sumi.ts
|
|
18799
|
-
import { spawnSync as
|
|
19070
|
+
import { spawnSync as spawnSync5 } from "child_process";
|
|
18800
19071
|
import { accessSync as accessSync2, constants as constants14, existsSync as existsSync8, lstatSync as lstatSync24, realpathSync as realpathSync10, statSync as statSync10 } from "fs";
|
|
18801
19072
|
import { delimiter as delimiter2, isAbsolute as isAbsolute20, join as join29, resolve as resolve20 } from "path";
|
|
18802
19073
|
|
|
@@ -18954,7 +19225,7 @@ function sumiPathPlan(home, cwd = process.cwd(), env = process.env) {
|
|
|
18954
19225
|
childEnv[key2] = env[key2];
|
|
18955
19226
|
let child2;
|
|
18956
19227
|
try {
|
|
18957
|
-
child2 =
|
|
19228
|
+
child2 = spawnSync5(executable2, ["--json", "--home", resolve20(home), "--cwd", resolve20(cwd)], {
|
|
18958
19229
|
cwd: resolve20(cwd),
|
|
18959
19230
|
env: childEnv,
|
|
18960
19231
|
encoding: "buffer",
|
|
@@ -19420,7 +19691,7 @@ function assertPinnedLauncherRuntimeSafe(runtime) {
|
|
|
19420
19691
|
|
|
19421
19692
|
// src/lib/retained-review-artifacts.ts
|
|
19422
19693
|
import { createHash as createHash26 } from "crypto";
|
|
19423
|
-
import { constants as constants17, closeSync as closeSync16, fstatSync as fstatSync16, fsyncSync as fsyncSync6, lstatSync as lstatSync27, mkdirSync as
|
|
19694
|
+
import { constants as constants17, closeSync as closeSync16, fstatSync as fstatSync16, fsyncSync as fsyncSync6, lstatSync as lstatSync27, mkdirSync as mkdirSync8, openSync as openSync16, readSync as readSync11, writeSync as writeSync4 } from "fs";
|
|
19424
19695
|
import { dirname as dirname21, isAbsolute as isAbsolute23, join as join30, resolve as resolve22, sep as sep13 } from "path";
|
|
19425
19696
|
var sha3 = (bytes) => createHash26("sha256").update(bytes).digest("hex");
|
|
19426
19697
|
var hex = (value) => typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
|
|
@@ -19550,7 +19821,7 @@ function writeReviewArtifactExclusive(change) {
|
|
|
19550
19821
|
for (let parent = dirname21(change.path);!lstatSync27(parent, { throwIfNoEntry: false }); parent = dirname21(parent))
|
|
19551
19822
|
missing2.push(parent);
|
|
19552
19823
|
for (const parent of missing2.reverse())
|
|
19553
|
-
|
|
19824
|
+
mkdirSync8(parent, { mode: 448 });
|
|
19554
19825
|
safe4(change.path);
|
|
19555
19826
|
privateStore(change.artifact.storeRoot);
|
|
19556
19827
|
for (let parent = dirname21(change.path);parent !== change.artifact.storeRoot; parent = dirname21(parent)) {
|
|
@@ -19800,7 +20071,7 @@ function treeHash(root) {
|
|
|
19800
20071
|
const rel = relative9(root, path);
|
|
19801
20072
|
if (stat2.isDirectory()) {
|
|
19802
20073
|
hash3.update(`d\x00${rel}\x00`);
|
|
19803
|
-
for (const name of
|
|
20074
|
+
for (const name of readdirSync11(path).sort())
|
|
19804
20075
|
visit2(join31(path, name));
|
|
19805
20076
|
return;
|
|
19806
20077
|
}
|
|
@@ -20695,7 +20966,7 @@ function planClaudeHookEventsUpdate(options) {
|
|
|
20695
20966
|
}
|
|
20696
20967
|
function atomicWrite2(path, content) {
|
|
20697
20968
|
assertSafePath(path);
|
|
20698
|
-
|
|
20969
|
+
mkdirSync9(dirname22(path), { recursive: true, mode: 448 });
|
|
20699
20970
|
const temporary = `${path}.skills-${randomUUID4()}`;
|
|
20700
20971
|
try {
|
|
20701
20972
|
writeFileSync6(temporary, content, { mode: 384, flag: "wx" });
|
|
@@ -20863,7 +21134,7 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
|
|
|
20863
21134
|
throw new Error("Local marketplace hook parent is not enabled in the unchanged Codex settings");
|
|
20864
21135
|
identity5 = { role: "reviewed-hook", pluginId: pluginId2, namespace: parts[1], pluginParent: parent, installation: "local-marketplace", marketplaceSourcePath: source.path, marketplaceSha256: source.sha256 };
|
|
20865
21136
|
}
|
|
20866
|
-
const versions =
|
|
21137
|
+
const versions = readdirSync11(parent).filter((name) => name !== ".codex-remote-plugin-install.json");
|
|
20867
21138
|
if (!versions.length || versions.length > 4096)
|
|
20868
21139
|
throw new Error("Reviewed native-hook parent has no bounded materializations");
|
|
20869
21140
|
for (const version2 of versions) {
|
|
@@ -20957,9 +21228,10 @@ function applyAgentIntegration(plan, options = {}) {
|
|
|
20957
21228
|
const alias = plan.rootAliases?.find((item) => item.agent === "codex" && (change.path === item.target || change.path.startsWith(item.target + "/")));
|
|
20958
21229
|
return lexical ? [lexical] : alias ? [alias.alias] : [];
|
|
20959
21230
|
});
|
|
20960
|
-
return withCodexCorpusWrite(roots, (assertCurrent) => applyAgentIntegrationUnlocked(plan, options, assertCurrent), options);
|
|
21231
|
+
return withCodexCorpusWrite(roots, (assertCurrent, admission) => applyAgentIntegrationUnlocked(plan, options, assertCurrent, admission), options);
|
|
20961
21232
|
}
|
|
20962
|
-
function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
|
|
21233
|
+
function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent, admission) {
|
|
21234
|
+
const fallback = codexAdmissionReceipt(admission);
|
|
20963
21235
|
for (const source of plan.reviewArtifactSources ?? [])
|
|
20964
21236
|
verifyReviewArtifactOriginal(source.path, source.sha256);
|
|
20965
21237
|
for (const source of plan.observedNativeSources ?? [])
|
|
@@ -21023,10 +21295,10 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
|
|
|
21023
21295
|
recheckRootAliases(aliases);
|
|
21024
21296
|
for (const agent of plan.retainedReviewChecks?.agents ?? [])
|
|
21025
21297
|
assertManagedAgentBridge(agent, { ...plan.retainedReviewChecks, dataDir: plan.dataDir });
|
|
21026
|
-
return { changed: [], backups, ...aliases.length ? { rootAliases: aliases } : {} };
|
|
21298
|
+
return { changed: [], backups, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback };
|
|
21027
21299
|
}
|
|
21028
21300
|
assertSafePath(backupRoot);
|
|
21029
|
-
|
|
21301
|
+
mkdirSync9(backupRoot, { recursive: true, mode: 448 });
|
|
21030
21302
|
chmodSync(backupRoot, 448);
|
|
21031
21303
|
for (const [index, change] of plan.changes.entries())
|
|
21032
21304
|
if (change.before !== null) {
|
|
@@ -21074,7 +21346,7 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
|
|
|
21074
21346
|
assertManagedAgentBridge(agent, { home: plan.managedAgentChecks.home, dataDir: plan.dataDir, projectDir: plan.managedAgentChecks.projectDir ?? plan.managedAgentChecks.home });
|
|
21075
21347
|
for (const agent of plan.retainedReviewChecks?.agents ?? [])
|
|
21076
21348
|
assertManagedAgentBridge(agent, { ...plan.retainedReviewChecks, dataDir: plan.dataDir });
|
|
21077
|
-
atomicWrite2(join31(backupRoot, "receipt.json"), JSON.stringify({ version: 1, changes: written.map((change) => ({ path: change.path, beforeHash: change.before === null ? null : sha4(change.before), afterHash: sha4(change.after) })), backups, ...plan.cacheWitnessUpgrade ? { cacheWitnessUpgrade: plan.cacheWitnessUpgrade } : {}, ...plan.retainedReviewArtifacts?.length ? { retainedReviewArtifacts: plan.retainedReviewArtifacts.map((item) => ({ path: item.path, ...item.artifact })) } : {}, ...aliases.length ? { rootAliases: aliases } : {} }) + `
|
|
21349
|
+
atomicWrite2(join31(backupRoot, "receipt.json"), JSON.stringify({ version: 1, changes: written.map((change) => ({ path: change.path, beforeHash: change.before === null ? null : sha4(change.before), afterHash: sha4(change.after) })), backups, ...plan.cacheWitnessUpgrade ? { cacheWitnessUpgrade: plan.cacheWitnessUpgrade } : {}, ...plan.retainedReviewArtifacts?.length ? { retainedReviewArtifacts: plan.retainedReviewArtifacts.map((item) => ({ path: item.path, ...item.artifact })) } : {}, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback }) + `
|
|
21078
21350
|
`);
|
|
21079
21351
|
} catch (error) {
|
|
21080
21352
|
assertCurrent();
|
|
@@ -21102,7 +21374,7 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
|
|
|
21102
21374
|
}
|
|
21103
21375
|
throw error;
|
|
21104
21376
|
}
|
|
21105
|
-
return { changed: plan.changes.map((change) => change.path), backups, ...aliases.length ? { rootAliases: aliases } : {} };
|
|
21377
|
+
return { changed: plan.changes.map((change) => change.path), backups, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback };
|
|
21106
21378
|
}
|
|
21107
21379
|
function syncArchiveDirectory(path) {
|
|
21108
21380
|
assertSafePath(path);
|
|
@@ -21142,9 +21414,10 @@ function archiveNativeSkills(inventory, options) {
|
|
|
21142
21414
|
throw new Error("CODEX_CORPUS_ROOT_UNVERIFIED");
|
|
21143
21415
|
return [...new Set([root, owner2].filter((value) => value !== undefined))];
|
|
21144
21416
|
});
|
|
21145
|
-
return withCodexCorpusWrite(roots, (assertCurrent) => archiveNativeSkillsUnlocked(inventory, options, assertCurrent), options);
|
|
21417
|
+
return withCodexCorpusWrite(roots, (assertCurrent, admission) => archiveNativeSkillsUnlocked(inventory, options, assertCurrent, admission), options);
|
|
21146
21418
|
}
|
|
21147
|
-
function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
|
|
21419
|
+
function archiveNativeSkillsUnlocked(inventory, options, assertCurrent, admission) {
|
|
21420
|
+
const fallback = codexAdmissionReceipt(admission);
|
|
21148
21421
|
const aliases = [...new Map(inventory.filter((entry) => entry.rootAlias).map((entry) => [entry.rootAlias.alias, entry.rootAlias])).values()];
|
|
21149
21422
|
if (aliases.length && !options.allowRootAliases)
|
|
21150
21423
|
throw new Error("Native migration requires explicit allowRootAliases for agent root aliases");
|
|
@@ -21162,7 +21435,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
|
|
|
21162
21435
|
throw new Error(`Native skill changed after planning: ${entry.path}`);
|
|
21163
21436
|
const targetManifest = options.targetManifest ? { schema: options.targetManifest.schema, digest: options.targetManifest.digest, targetCount: options.targetManifest.targets.length } : undefined;
|
|
21164
21437
|
if (!selected.length)
|
|
21165
|
-
return { entries: [], ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {} };
|
|
21438
|
+
return { entries: [], ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback };
|
|
21166
21439
|
const operationId = randomUUID4(), archiveRoot = join31(options.dataDir ?? getDataDir(), "migration", operationId, "native"), receiptPath = join31(archiveRoot, "receipt.json");
|
|
21167
21440
|
const entries = selected.map((entry, index) => ({
|
|
21168
21441
|
source: entry.vendor ? join31(entry.path, "SKILL.md") : entry.path,
|
|
@@ -21171,7 +21444,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
|
|
|
21171
21444
|
...entry.vendor ? { discoveryOnly: true } : {},
|
|
21172
21445
|
status: "planned"
|
|
21173
21446
|
}));
|
|
21174
|
-
const journal = { version: 2, operationId, status: "planned", entries, ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {} };
|
|
21447
|
+
const journal = { version: 2, operationId, status: "planned", entries, ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback };
|
|
21175
21448
|
const moved = [];
|
|
21176
21449
|
const verifyArchive = (entry) => {
|
|
21177
21450
|
assertSafePath(entry.archive);
|
|
@@ -21185,7 +21458,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
|
|
|
21185
21458
|
const created = [];
|
|
21186
21459
|
for (let path = archiveRoot;!existsSync9(path); path = dirname22(path))
|
|
21187
21460
|
created.push(path);
|
|
21188
|
-
|
|
21461
|
+
mkdirSync9(archiveRoot, { recursive: true, mode: 448 });
|
|
21189
21462
|
try {
|
|
21190
21463
|
for (const directory2 of created)
|
|
21191
21464
|
syncArchiveDirectory(directory2);
|
|
@@ -21268,7 +21541,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
|
|
|
21268
21541
|
} catch {}
|
|
21269
21542
|
throw new Error(`Native archive failed; inspect the recovery journal at ${receiptPath} before retrying.`, { cause: error });
|
|
21270
21543
|
}
|
|
21271
|
-
return { entries: entries.map(({ status, conflict, ...entry }) => entry), receiptPath, ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {} };
|
|
21544
|
+
return { entries: entries.map(({ status, conflict, ...entry }) => entry), receiptPath, ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback };
|
|
21272
21545
|
}
|
|
21273
21546
|
function classifiedCodexPluginCacheCopy(entry, cache, read2, admit) {
|
|
21274
21547
|
try {
|
|
@@ -21716,7 +21989,7 @@ function packageSourceRoots(source) {
|
|
|
21716
21989
|
function containsSkillDirectories(path) {
|
|
21717
21990
|
let entries;
|
|
21718
21991
|
try {
|
|
21719
|
-
entries =
|
|
21992
|
+
entries = readdirSync12(path);
|
|
21720
21993
|
} catch {
|
|
21721
21994
|
return false;
|
|
21722
21995
|
}
|
|
@@ -21811,12 +22084,16 @@ function writeManagedAgentSkill(params) {
|
|
|
21811
22084
|
agent: params.agent,
|
|
21812
22085
|
path: result.path,
|
|
21813
22086
|
action: result.action,
|
|
21814
|
-
...result.reason ? { reason: result.reason } : {}
|
|
22087
|
+
...result.reason ? { reason: result.reason } : {},
|
|
22088
|
+
...result.nativeAdmission ? { nativeAdmission: result.nativeAdmission, nativeAdmissionProbe: result.nativeAdmissionProbe } : {}
|
|
21815
22089
|
};
|
|
21816
22090
|
}
|
|
21817
22091
|
function writeManagedSkillDir(dir, skillMd, options) {
|
|
21818
22092
|
const root = options.dryRun ? undefined : codexCorpusRootForPath(dir);
|
|
21819
|
-
return withCodexCorpusWrite(root ? [root] : [], (assertCurrent) =>
|
|
22093
|
+
return withCodexCorpusWrite(root ? [root] : [], (assertCurrent, admission) => {
|
|
22094
|
+
const result = writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent);
|
|
22095
|
+
return { ...result, ...codexAdmissionReceipt(admission) };
|
|
22096
|
+
}, options);
|
|
21820
22097
|
}
|
|
21821
22098
|
function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
|
|
21822
22099
|
const skillMdPath = join32(dir, "SKILL.md");
|
|
@@ -21857,8 +22134,8 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
|
|
|
21857
22134
|
if (options.dryRun)
|
|
21858
22135
|
return { action, path: skillMdPath };
|
|
21859
22136
|
const parentDir = dirname23(dir);
|
|
21860
|
-
|
|
21861
|
-
const transactionDir =
|
|
22137
|
+
mkdirSync10(parentDir, { recursive: true });
|
|
22138
|
+
const transactionDir = mkdtempSync2(join32(parentDir, `.hasna-skills-write-${basename12(dir)}-`));
|
|
21862
22139
|
const candidateDir = join32(transactionDir, "candidate");
|
|
21863
22140
|
const backupDir = join32(transactionDir, "backup");
|
|
21864
22141
|
const candidateSkillMdPath = join32(candidateDir, "SKILL.md");
|
|
@@ -21876,7 +22153,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
|
|
|
21876
22153
|
if (options.resourceDir) {
|
|
21877
22154
|
cpSync2(options.resourceDir, candidateDir, { recursive: true, force: true });
|
|
21878
22155
|
} else {
|
|
21879
|
-
|
|
22156
|
+
mkdirSync10(candidateDir, { recursive: true });
|
|
21880
22157
|
}
|
|
21881
22158
|
writeFileSync7(candidateSkillMdPath, skillMd.endsWith(`
|
|
21882
22159
|
`) ? skillMd : `${skillMd}
|
|
@@ -21900,7 +22177,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
|
|
|
21900
22177
|
try {
|
|
21901
22178
|
assertCurrent();
|
|
21902
22179
|
if (existsSync10(dir))
|
|
21903
|
-
|
|
22180
|
+
rmSync3(dir, { recursive: true, force: true });
|
|
21904
22181
|
renameDirectory(backupDir, dir);
|
|
21905
22182
|
originalMoved = false;
|
|
21906
22183
|
} catch (rollbackError) {
|
|
@@ -21913,22 +22190,26 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
|
|
|
21913
22190
|
if (!preserveTransaction) {
|
|
21914
22191
|
try {
|
|
21915
22192
|
assertCurrent();
|
|
21916
|
-
|
|
22193
|
+
rmSync3(transactionDir, { recursive: true, force: true });
|
|
21917
22194
|
} catch {}
|
|
21918
22195
|
}
|
|
21919
22196
|
}
|
|
21920
22197
|
return { action, path: skillMdPath };
|
|
21921
22198
|
}
|
|
21922
22199
|
function removeManagedAgentSkill(skill, agent, homeDir2 = homedir3(), options = {}) {
|
|
22200
|
+
const record5 = codexAdmissionRecord(options);
|
|
21923
22201
|
const dir = join32(agentGlobalSkillsDir(agent, homeDir2), skill);
|
|
21924
22202
|
const root = codexCorpusRootForPath(dir);
|
|
21925
|
-
return withCodexCorpusWrite(root ? [root] : [], () =>
|
|
22203
|
+
return withCodexCorpusWrite(root ? [root] : [], (_assertCurrent, admission) => {
|
|
22204
|
+
record5.deliver(admission);
|
|
22205
|
+
return removeManagedAgentSkillUnlocked(skill, agent, homeDir2, options);
|
|
22206
|
+
}, options, record5.policy);
|
|
21926
22207
|
}
|
|
21927
22208
|
function removeManagedAgentSkillUnlocked(skill, agent, homeDir2 = homedir3(), options = {}) {
|
|
21928
22209
|
const dir = join32(agentGlobalSkillsDir(agent, homeDir2), skill);
|
|
21929
22210
|
if (!hasSkillsOwnershipMarker(dir))
|
|
21930
22211
|
return false;
|
|
21931
|
-
|
|
22212
|
+
rmSync3(dir, { recursive: true, force: true });
|
|
21932
22213
|
return true;
|
|
21933
22214
|
}
|
|
21934
22215
|
function sourceSkillMd(skillPath, name, description, kind, preferBundledDocs = false) {
|
|
@@ -21975,7 +22256,7 @@ function resolveSkillAlias(name) {
|
|
|
21975
22256
|
}
|
|
21976
22257
|
|
|
21977
22258
|
// src/lib/project-state.ts
|
|
21978
|
-
import { existsSync as existsSync11, mkdirSync as
|
|
22259
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync11, readFileSync as readFileSync21, writeFileSync as writeFileSync8 } from "fs";
|
|
21979
22260
|
import { join as join33 } from "path";
|
|
21980
22261
|
var VALID_PIN_SOURCES = [
|
|
21981
22262
|
"official",
|
|
@@ -22022,7 +22303,7 @@ function ensureProjectConfig(targetDir = process.cwd()) {
|
|
|
22022
22303
|
}
|
|
22023
22304
|
function saveProjectConfig(config, targetDir = process.cwd()) {
|
|
22024
22305
|
const dir = getProjectStateDir(targetDir);
|
|
22025
|
-
|
|
22306
|
+
mkdirSync11(dir, { recursive: true });
|
|
22026
22307
|
const normalized2 = normalizeProjectConfig({ ...config, updatedAt: new Date().toISOString() });
|
|
22027
22308
|
writeFileSync8(getProjectConfigPath(targetDir), JSON.stringify(normalized2, null, 2) + `
|
|
22028
22309
|
`);
|
|
@@ -22291,15 +22572,20 @@ function installSkillForAgent(name, options, generateSkillMd) {
|
|
|
22291
22572
|
codexCommand: options.codexCommand,
|
|
22292
22573
|
codexSha256: options.codexSha256
|
|
22293
22574
|
});
|
|
22575
|
+
const fallback = result.nativeAdmission ? { nativeAdmission: result.nativeAdmission, nativeAdmissionProbe: result.nativeAdmissionProbe } : {};
|
|
22294
22576
|
if (result.action === "skip") {
|
|
22295
|
-
return { skill: canonicalName, success: false, error: result.reason ?? "skipped", path: result.path };
|
|
22577
|
+
return { skill: canonicalName, success: false, error: result.reason ?? "skipped", path: result.path, ...fallback };
|
|
22296
22578
|
}
|
|
22297
|
-
return { skill: canonicalName, success: true, path: result.path };
|
|
22579
|
+
return { skill: canonicalName, success: true, path: result.path, ...fallback };
|
|
22298
22580
|
}
|
|
22299
22581
|
function removeSkillForAgent(name, options) {
|
|
22582
|
+
const record5 = codexAdmissionRecord(options);
|
|
22300
22583
|
const dir = getAgentSkillPath(name, options.agent, options.scope ?? "global", options.projectDir);
|
|
22301
22584
|
const root = codexCorpusRootForPath(dir);
|
|
22302
|
-
return withCodexCorpusWrite(root ? [root] : [], () =>
|
|
22585
|
+
return withCodexCorpusWrite(root ? [root] : [], (_assertCurrent, admission) => {
|
|
22586
|
+
record5.deliver(admission);
|
|
22587
|
+
return removeSkillForAgentUnlocked(name, options);
|
|
22588
|
+
}, options, record5.policy);
|
|
22303
22589
|
}
|
|
22304
22590
|
function removeSkillForAgentUnlocked(name, options) {
|
|
22305
22591
|
const canonicalName = getCanonicalSkillName(name);
|
|
@@ -22307,7 +22593,7 @@ function removeSkillForAgentUnlocked(name, options) {
|
|
|
22307
22593
|
const dir = getAgentSkillPath(canonicalName, options.agent, scope, options.projectDir);
|
|
22308
22594
|
if (!hasSkillsOwnershipMarker(dir))
|
|
22309
22595
|
return false;
|
|
22310
|
-
|
|
22596
|
+
rmSync4(dir, { recursive: true, force: true });
|
|
22311
22597
|
return true;
|
|
22312
22598
|
}
|
|
22313
22599
|
function resolveAgentSkillMd(name, generateSkillMd) {
|
|
@@ -24465,13 +24751,13 @@ function assertProjectDiscovery(agent, directories, home, canonical9 = resolve27
|
|
|
24465
24751
|
for (const name of ["plugin", "plugins"]) {
|
|
24466
24752
|
const path = canonical9(join38(directory2, ".sumi", name));
|
|
24467
24753
|
safe6(path);
|
|
24468
|
-
if (lstatSync32(path, { throwIfNoEntry: false })?.isDirectory() &&
|
|
24754
|
+
if (lstatSync32(path, { throwIfNoEntry: false })?.isDirectory() && readdirSync13(path).length)
|
|
24469
24755
|
throw new Error(`NATIVE_SKILL_DRIFT: project Sumi plugins require a dedicated discovery review: ${path}`);
|
|
24470
24756
|
}
|
|
24471
24757
|
if (agent === "claude") {
|
|
24472
24758
|
const commands = canonical9(join38(directory2, ".claude/commands"));
|
|
24473
24759
|
safe6(commands);
|
|
24474
|
-
if (lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() &&
|
|
24760
|
+
if (lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync13(commands).length)
|
|
24475
24761
|
throw new Error("NATIVE_SKILL_DRIFT: legacy project command discovery requires a dedicated format adapter");
|
|
24476
24762
|
}
|
|
24477
24763
|
}
|
|
@@ -24620,7 +24906,7 @@ function resolveAgentDiscovery(options) {
|
|
|
24620
24906
|
for (const path of plugins) {
|
|
24621
24907
|
safe6(path);
|
|
24622
24908
|
if (lstatSync32(path, { throwIfNoEntry: false })?.isDirectory())
|
|
24623
|
-
for (const name of
|
|
24909
|
+
for (const name of readdirSync13(path).sort()) {
|
|
24624
24910
|
if (name === "skills-cli.js" && path === plugins[1])
|
|
24625
24911
|
continue;
|
|
24626
24912
|
const target = join38(path, name);
|
|
@@ -24631,7 +24917,7 @@ function resolveAgentDiscovery(options) {
|
|
|
24631
24917
|
}
|
|
24632
24918
|
for (const root2 of roots) {
|
|
24633
24919
|
safe6(root2);
|
|
24634
|
-
if (lstatSync32(root2, { throwIfNoEntry: false })?.isDirectory() &&
|
|
24920
|
+
if (lstatSync32(root2, { throwIfNoEntry: false })?.isDirectory() && readdirSync13(root2).some((name) => name.endsWith(".md")))
|
|
24635
24921
|
unresolved("flat markdown skills require a dedicated native migration adapter");
|
|
24636
24922
|
}
|
|
24637
24923
|
}
|
|
@@ -24675,7 +24961,7 @@ function resolveAgentDiscovery(options) {
|
|
|
24675
24961
|
safe6(builtinRoot);
|
|
24676
24962
|
if (!lstatSync32(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
|
|
24677
24963
|
unresolved("installed Gemini builtin root is missing");
|
|
24678
|
-
for (const name of
|
|
24964
|
+
for (const name of readdirSync13(builtinRoot).sort()) {
|
|
24679
24965
|
const text2 = witness(join38(builtinRoot, name, "SKILL.md"));
|
|
24680
24966
|
const match = text2?.match(/^---\r?\n[\s\S]*?^name:\s*([a-z0-9][a-z0-9-]*)\s*$/m);
|
|
24681
24967
|
if (!match?.[1] || builtinNames.includes(match[1]))
|
|
@@ -24773,7 +25059,7 @@ function resolveAgentDiscovery(options) {
|
|
|
24773
25059
|
unresolved("plugin hooks require a separate no-skill-injection review");
|
|
24774
25060
|
const commands = join38(root2, "commands");
|
|
24775
25061
|
safe6(commands);
|
|
24776
|
-
if (agent === "claude" && (manifest.commands !== undefined || lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() &&
|
|
25062
|
+
if (agent === "claude" && (manifest.commands !== undefined || lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync13(commands).length))
|
|
24777
25063
|
unresolved("legacy command discovery requires retirement or a dedicated format adapter");
|
|
24778
25064
|
const rootSkill = witness(join38(root2, "SKILL.md"));
|
|
24779
25065
|
if (rootSkill !== null)
|
|
@@ -24795,7 +25081,7 @@ function resolveAgentDiscovery(options) {
|
|
|
24795
25081
|
const installed = registrations === null ? {} : parseConfig(registrations, join38(home, ".claude/plugins/installed_plugins.json")).plugins;
|
|
24796
25082
|
const commands = canonical9(join38(home, ".claude/commands"));
|
|
24797
25083
|
safe6(commands);
|
|
24798
|
-
if (lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() &&
|
|
25084
|
+
if (lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync13(commands).length)
|
|
24799
25085
|
unresolved("legacy home command discovery requires a dedicated format adapter");
|
|
24800
25086
|
for (const [id, enabled] of Object.entries(config.enabledPlugins ?? {})) {
|
|
24801
25087
|
if (enabled === false)
|
|
@@ -24837,7 +25123,7 @@ function resolveAgentDiscovery(options) {
|
|
|
24837
25123
|
}
|
|
24838
25124
|
const localPlugins = join38(home, ".config/opencode/plugins");
|
|
24839
25125
|
safe6(localPlugins);
|
|
24840
|
-
if (lstatSync32(localPlugins, { throwIfNoEntry: false }) &&
|
|
25126
|
+
if (lstatSync32(localPlugins, { throwIfNoEntry: false }) && readdirSync13(localPlugins).some((name) => name !== "skills-cli.js"))
|
|
24841
25127
|
unresolved("additional local plugin hooks require review");
|
|
24842
25128
|
} else if (agent === "sumi") {
|
|
24843
25129
|
if ((config.plugin?.length ?? 0) > 0 || (config.plugins?.length ?? 0) > 0 || sources.some((source) => source.path !== canonical9(configPath) && source.path !== canonical9(join38(sumiConfigDirectory(home), "sumi.jsonc")) && source.sha256 !== null))
|
|
@@ -24856,7 +25142,7 @@ function resolveAgentDiscovery(options) {
|
|
|
24856
25142
|
const directory2 = join38(home, ".gemini/extensions");
|
|
24857
25143
|
safe6(directory2);
|
|
24858
25144
|
if (lstatSync32(directory2, { throwIfNoEntry: false }))
|
|
24859
|
-
for (const name of
|
|
25145
|
+
for (const name of readdirSync13(directory2)) {
|
|
24860
25146
|
const root2 = join38(directory2, name);
|
|
24861
25147
|
safe6(root2);
|
|
24862
25148
|
if (!lstatSync32(root2)?.isDirectory())
|
|
@@ -24901,7 +25187,7 @@ function physicalPath(path) {
|
|
|
24901
25187
|
}
|
|
24902
25188
|
return resolve28(realpathSync14(cursor), ...suffix);
|
|
24903
25189
|
}
|
|
24904
|
-
function
|
|
25190
|
+
function contains2(root2, path) {
|
|
24905
25191
|
return path === root2 || path.startsWith(root2 + sep16);
|
|
24906
25192
|
}
|
|
24907
25193
|
function configuredRoots(home, explicitHome) {
|
|
@@ -24954,14 +25240,14 @@ function assertPortableAuthoringPath(path, options = {}) {
|
|
|
24954
25240
|
const defaults = NATIVE_DISCOVERY_ROOTS.map((parts) => join39(home, ...parts));
|
|
24955
25241
|
defaults.push(join39(home, ".codex/plugins/cache"), join39(home, ".claude/plugins/cache"), join39(home, ".claude/plugins/synced"), join39(home, ".gemini/extensions"));
|
|
24956
25242
|
for (const root2 of defaults) {
|
|
24957
|
-
if (candidates.some((candidate2) =>
|
|
25243
|
+
if (candidates.some((candidate2) => contains2(resolve28(root2), candidate2) || contains2(physicalPath(root2), candidate2)))
|
|
24958
25244
|
native ??= root2;
|
|
24959
25245
|
}
|
|
24960
25246
|
if (native) {
|
|
24961
25247
|
throw new Error(`Refusing portable Skills authoring below native discovery root '${native}': ${lexical}. Set HASNA_SKILLS_DIR to a private authoring corpus outside native roots.`);
|
|
24962
25248
|
}
|
|
24963
25249
|
for (const root2 of configuredRoots(home, options.homeDir !== undefined)) {
|
|
24964
|
-
if (candidates.some((candidate2) =>
|
|
25250
|
+
if (candidates.some((candidate2) => contains2(resolve28(root2), candidate2) || contains2(physicalPath(root2), candidate2))) {
|
|
24965
25251
|
throw new Error(`Refusing portable Skills authoring below configured native discovery root: ${lexical}`);
|
|
24966
25252
|
}
|
|
24967
25253
|
}
|
|
@@ -25004,7 +25290,7 @@ function listPortableSkills(options = {}) {
|
|
|
25004
25290
|
if (!safeIsDirectory(root2))
|
|
25005
25291
|
return [];
|
|
25006
25292
|
const skills = [];
|
|
25007
|
-
for (const entry of
|
|
25293
|
+
for (const entry of readdirSync14(root2).sort()) {
|
|
25008
25294
|
if (entry.startsWith("."))
|
|
25009
25295
|
continue;
|
|
25010
25296
|
const path = join40(root2, entry);
|
|
@@ -25048,7 +25334,7 @@ function scaffoldPortableSkill(name, options = {}) {
|
|
|
25048
25334
|
if (existsSync14(skillPath)) {
|
|
25049
25335
|
if (!options.overwrite)
|
|
25050
25336
|
throw new Error(`Skill '${skillName}' already exists at ${skillPath}`);
|
|
25051
|
-
|
|
25337
|
+
rmSync5(skillPath, { recursive: true, force: true });
|
|
25052
25338
|
}
|
|
25053
25339
|
const kind = options.kind ?? "executable";
|
|
25054
25340
|
const description = options.description ?? `${displayName(skillName)} skill`;
|
|
@@ -25075,7 +25361,7 @@ function portPortableSkillDirectory(sourceDir, options = {}) {
|
|
|
25075
25361
|
};
|
|
25076
25362
|
const imported = [];
|
|
25077
25363
|
const skipped = [];
|
|
25078
|
-
const entries =
|
|
25364
|
+
const entries = readdirSync14(absoluteSource, { withFileTypes: true }).map((entry) => entry.name).filter((entryName) => !entryName.startsWith(".")).sort();
|
|
25079
25365
|
for (const entryName of entries) {
|
|
25080
25366
|
const childPath = join40(absoluteSource, entryName);
|
|
25081
25367
|
if (!safeIsDirectory(childPath))
|
|
@@ -25120,11 +25406,11 @@ function physicalImportPath(path) {
|
|
|
25120
25406
|
function assertDisjointImportPaths(source, destination) {
|
|
25121
25407
|
const sourcePath = realpathSync15(source);
|
|
25122
25408
|
const destinationPath = physicalImportPath(destination);
|
|
25123
|
-
const
|
|
25409
|
+
const contains3 = (parent, child2) => {
|
|
25124
25410
|
const path = relative11(parent, child2);
|
|
25125
25411
|
return path === "" || !isAbsolute29(path) && path !== ".." && !path.startsWith(`..${sep17}`);
|
|
25126
25412
|
};
|
|
25127
|
-
if (
|
|
25413
|
+
if (contains3(sourcePath, destinationPath) || contains3(destinationPath, sourcePath)) {
|
|
25128
25414
|
throw new Error("Source and destination skill directories must not overlap");
|
|
25129
25415
|
}
|
|
25130
25416
|
}
|
|
@@ -25151,9 +25437,9 @@ function portPortableSkill(sourcePath, options = {}) {
|
|
|
25151
25437
|
if (existsSync14(destination)) {
|
|
25152
25438
|
if (!options.overwrite)
|
|
25153
25439
|
throw new Error(`Skill '${skillName}' already exists at ${destination}`);
|
|
25154
|
-
|
|
25440
|
+
rmSync5(destination, { recursive: true, force: true });
|
|
25155
25441
|
}
|
|
25156
|
-
|
|
25442
|
+
mkdirSync12(dirname28(destination), { recursive: true });
|
|
25157
25443
|
copySkillDirectory(absoluteSource, destination);
|
|
25158
25444
|
const base = {
|
|
25159
25445
|
...inferred,
|
|
@@ -25195,7 +25481,7 @@ function writeCorpusSkill(input, options = {}) {
|
|
|
25195
25481
|
const skillPath = join40(root2, name);
|
|
25196
25482
|
assertPortableAuthoringPath(skillPath, options);
|
|
25197
25483
|
const created = !existsSync14(skillPath);
|
|
25198
|
-
|
|
25484
|
+
mkdirSync12(skillPath, { recursive: true });
|
|
25199
25485
|
writeFileSync9(join40(skillPath, "SKILL.md"), input.skillMd);
|
|
25200
25486
|
const manifest = buildCorpusManifest(input, name);
|
|
25201
25487
|
writeSkillJsonWithHash(skillPath, manifest);
|
|
@@ -25209,8 +25495,8 @@ function installCorpusSkillAtomically(input, options = {}) {
|
|
|
25209
25495
|
const target = join40(root2, name);
|
|
25210
25496
|
assertPortableAuthoringPath(target, options);
|
|
25211
25497
|
const created = !existsSync14(target);
|
|
25212
|
-
|
|
25213
|
-
const staging =
|
|
25498
|
+
mkdirSync12(root2, { recursive: true });
|
|
25499
|
+
const staging = mkdtempSync3(join40(root2, `.pull-${name}-`));
|
|
25214
25500
|
let moved = false;
|
|
25215
25501
|
let backup = null;
|
|
25216
25502
|
try {
|
|
@@ -25218,16 +25504,16 @@ function installCorpusSkillAtomically(input, options = {}) {
|
|
|
25218
25504
|
const manifest = buildCorpusManifest(input, name);
|
|
25219
25505
|
writeSkillJsonWithHash(staging, manifest);
|
|
25220
25506
|
if (existsSync14(target)) {
|
|
25221
|
-
backup =
|
|
25507
|
+
backup = mkdtempSync3(join40(root2, `.pull-backup-${name}-`));
|
|
25222
25508
|
renameSync6(target, join40(backup, name));
|
|
25223
25509
|
moved = true;
|
|
25224
25510
|
}
|
|
25225
25511
|
renameSync6(staging, target);
|
|
25226
25512
|
if (moved && backup)
|
|
25227
|
-
|
|
25513
|
+
rmSync5(backup, { recursive: true, force: true });
|
|
25228
25514
|
return { name, path: target, manifest, created };
|
|
25229
25515
|
} catch (error) {
|
|
25230
|
-
|
|
25516
|
+
rmSync5(staging, { recursive: true, force: true });
|
|
25231
25517
|
if (moved && backup && existsSync14(join40(backup, name))) {
|
|
25232
25518
|
try {
|
|
25233
25519
|
renameSync6(join40(backup, name), target);
|
|
@@ -25523,7 +25809,7 @@ function discoverSkillsInDir(dir, source = "custom") {
|
|
|
25523
25809
|
return [];
|
|
25524
25810
|
const result = [];
|
|
25525
25811
|
try {
|
|
25526
|
-
const entries =
|
|
25812
|
+
const entries = readdirSync15(dir, { withFileTypes: true });
|
|
25527
25813
|
for (const entry of entries) {
|
|
25528
25814
|
if (!entry.isDirectory())
|
|
25529
25815
|
continue;
|
|
@@ -25559,7 +25845,7 @@ function findExtensionSkillPath(name) {
|
|
|
25559
25845
|
if (!config.extensionsDir || !existsSync15(config.extensionsDir))
|
|
25560
25846
|
return null;
|
|
25561
25847
|
try {
|
|
25562
|
-
const entries =
|
|
25848
|
+
const entries = readdirSync15(config.extensionsDir, { withFileTypes: true });
|
|
25563
25849
|
for (const entry of entries) {
|
|
25564
25850
|
if (!entry.isDirectory())
|
|
25565
25851
|
continue;
|
|
@@ -25634,7 +25920,7 @@ function getAllTags(catalog) {
|
|
|
25634
25920
|
}
|
|
25635
25921
|
// src/lib/run-state.ts
|
|
25636
25922
|
import { createHash as createHash31, randomBytes } from "crypto";
|
|
25637
|
-
import { existsSync as existsSync16, mkdirSync as
|
|
25923
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync13, readFileSync as readFileSync28, readdirSync as readdirSync16, statSync as statSync14, writeFileSync as writeFileSync10 } from "fs";
|
|
25638
25924
|
import { extname, join as join42, relative as relative12 } from "path";
|
|
25639
25925
|
function createSkillRun(params, targetDir = process.cwd()) {
|
|
25640
25926
|
const now = new Date;
|
|
@@ -25645,9 +25931,9 @@ function createSkillRun(params, targetDir = process.cwd()) {
|
|
|
25645
25931
|
const runDir = join42(root2, "runs", day, id);
|
|
25646
25932
|
const logsDir = join42(runDir, "logs");
|
|
25647
25933
|
const exportDir = join42(root2, "exports", skillName, id);
|
|
25648
|
-
|
|
25649
|
-
|
|
25650
|
-
|
|
25934
|
+
mkdirSync13(logsDir, { recursive: true });
|
|
25935
|
+
mkdirSync13(exportDir, { recursive: true });
|
|
25936
|
+
mkdirSync13(join42(root2, "tmp"), { recursive: true });
|
|
25651
25937
|
const record5 = {
|
|
25652
25938
|
id,
|
|
25653
25939
|
skill: skillName,
|
|
@@ -25714,11 +26000,11 @@ function listSkillRuns(targetDir = process.cwd(), limit = 50) {
|
|
|
25714
26000
|
if (!existsSync16(runsRoot))
|
|
25715
26001
|
return [];
|
|
25716
26002
|
const records = [];
|
|
25717
|
-
for (const day of
|
|
26003
|
+
for (const day of readdirSync16(runsRoot).sort().reverse()) {
|
|
25718
26004
|
const dayDir = join42(runsRoot, day);
|
|
25719
26005
|
if (!statSync14(dayDir).isDirectory())
|
|
25720
26006
|
continue;
|
|
25721
|
-
for (const runId of
|
|
26007
|
+
for (const runId of readdirSync16(dayDir).sort().reverse()) {
|
|
25722
26008
|
const record5 = readRunRecord(join42(dayDir, runId));
|
|
25723
26009
|
if (record5)
|
|
25724
26010
|
records.push(record5);
|
|
@@ -25732,7 +26018,7 @@ function findSkillRun(runId, targetDir = process.cwd()) {
|
|
|
25732
26018
|
const runsRoot = join42(getProjectStateDir(targetDir), "runs");
|
|
25733
26019
|
if (!existsSync16(runsRoot))
|
|
25734
26020
|
return null;
|
|
25735
|
-
for (const day of
|
|
26021
|
+
for (const day of readdirSync16(runsRoot)) {
|
|
25736
26022
|
const record5 = readRunRecord(join42(runsRoot, day, runId));
|
|
25737
26023
|
if (record5)
|
|
25738
26024
|
return record5;
|
|
@@ -25778,7 +26064,7 @@ function readRunRecord(runDir) {
|
|
|
25778
26064
|
}
|
|
25779
26065
|
function walkFiles(dir) {
|
|
25780
26066
|
const files = [];
|
|
25781
|
-
for (const entry of
|
|
26067
|
+
for (const entry of readdirSync16(dir)) {
|
|
25782
26068
|
const full = join42(dir, entry);
|
|
25783
26069
|
if (statSync14(full).isDirectory())
|
|
25784
26070
|
files.push(...walkFiles(full));
|
|
@@ -47286,7 +47572,7 @@ async function createRemoteSkillsClient(env = process.env) {
|
|
|
47286
47572
|
return connection ? new RemoteSkillsClient(connection.apiKey, connection.apiOrigin) : null;
|
|
47287
47573
|
}
|
|
47288
47574
|
// src/lib/scheduler.ts
|
|
47289
|
-
import { existsSync as existsSync17, readFileSync as readFileSync29, writeFileSync as writeFileSync11, mkdirSync as
|
|
47575
|
+
import { existsSync as existsSync17, readFileSync as readFileSync29, writeFileSync as writeFileSync11, mkdirSync as mkdirSync14 } from "fs";
|
|
47290
47576
|
import { join as join43 } from "path";
|
|
47291
47577
|
function getSchedulesPath(targetDir = process.cwd()) {
|
|
47292
47578
|
return join43(targetDir, ".skills", "schedules.json");
|
|
@@ -47304,7 +47590,7 @@ function saveSchedules(data, targetDir = process.cwd()) {
|
|
|
47304
47590
|
const path = getSchedulesPath(targetDir);
|
|
47305
47591
|
const dir = join43(targetDir, ".skills");
|
|
47306
47592
|
if (!existsSync17(dir))
|
|
47307
|
-
|
|
47593
|
+
mkdirSync14(dir, { recursive: true });
|
|
47308
47594
|
writeFileSync11(path, JSON.stringify(data, null, 2));
|
|
47309
47595
|
}
|
|
47310
47596
|
function validateCronField(expr, min, max, label) {
|
|
@@ -47518,7 +47804,7 @@ function revisionIdOfRecord(record10) {
|
|
|
47518
47804
|
return revisionIdOf(record10);
|
|
47519
47805
|
}
|
|
47520
47806
|
// src/lib/pull.ts
|
|
47521
|
-
import { existsSync as existsSync18, mkdirSync as
|
|
47807
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync15, mkdtempSync as mkdtempSync4, readFileSync as readFileSync30, renameSync as renameSync7, rmSync as rmSync6, writeFileSync as writeFileSync12 } from "fs";
|
|
47522
47808
|
import { dirname as dirname29, join as join44 } from "path";
|
|
47523
47809
|
|
|
47524
47810
|
// src/lib/skill-bundles.ts
|
|
@@ -47713,7 +47999,7 @@ function reconcileTombstone(slug2, corpusOptions) {
|
|
|
47713
47999
|
if (!hasSkillsOwnershipMarker(target)) {
|
|
47714
48000
|
return { name: slug2, success: true, tombstoned: true, removed: false, leftInPlace: true };
|
|
47715
48001
|
}
|
|
47716
|
-
|
|
48002
|
+
rmSync6(target, { recursive: true, force: true });
|
|
47717
48003
|
return { name: slug2, success: true, tombstoned: true, removed: true };
|
|
47718
48004
|
}
|
|
47719
48005
|
function readPullMarker(dir) {
|
|
@@ -47852,16 +48138,16 @@ function verifyBundleResponseBytes(buffer, response, verify = {}) {
|
|
|
47852
48138
|
}
|
|
47853
48139
|
function installBundleAtomically(name, entries, options = {}, marker = {}) {
|
|
47854
48140
|
const root2 = getPortableSkillsRoot(options);
|
|
47855
|
-
|
|
48141
|
+
mkdirSync15(root2, { recursive: true });
|
|
47856
48142
|
const target = join44(root2, name);
|
|
47857
48143
|
const created = !existsSync18(target);
|
|
47858
|
-
const staging =
|
|
48144
|
+
const staging = mkdtempSync4(join44(root2, `.pull-${name}-`));
|
|
47859
48145
|
let moved = false;
|
|
47860
48146
|
let backup = null;
|
|
47861
48147
|
try {
|
|
47862
48148
|
for (const entry of entries) {
|
|
47863
48149
|
const destination = join44(staging, entry.path);
|
|
47864
|
-
|
|
48150
|
+
mkdirSync15(dirname29(destination), { recursive: true });
|
|
47865
48151
|
writeFileSync12(destination, entry.bytes, { mode: entry.mode });
|
|
47866
48152
|
}
|
|
47867
48153
|
writePullMarker(staging, {
|
|
@@ -47873,15 +48159,15 @@ function installBundleAtomically(name, entries, options = {}, marker = {}) {
|
|
|
47873
48159
|
...marker.revisionId ? { revisionId: marker.revisionId } : {}
|
|
47874
48160
|
});
|
|
47875
48161
|
if (existsSync18(target)) {
|
|
47876
|
-
backup =
|
|
48162
|
+
backup = mkdtempSync4(join44(root2, `.pull-backup-${name}-`));
|
|
47877
48163
|
renameSync7(target, join44(backup, name));
|
|
47878
48164
|
moved = true;
|
|
47879
48165
|
}
|
|
47880
48166
|
renameSync7(staging, target);
|
|
47881
48167
|
if (moved && backup)
|
|
47882
|
-
|
|
48168
|
+
rmSync6(backup, { recursive: true, force: true });
|
|
47883
48169
|
} catch (error61) {
|
|
47884
|
-
|
|
48170
|
+
rmSync6(staging, { recursive: true, force: true });
|
|
47885
48171
|
if (moved && backup && existsSync18(join44(backup, name))) {
|
|
47886
48172
|
try {
|
|
47887
48173
|
renameSync7(join44(backup, name), target);
|
|
@@ -48764,7 +49050,7 @@ function findSkillsParityForMcpTool(tool) {
|
|
|
48764
49050
|
return SKILLS_CLI_MCP_PARITY.find((entry) => entry.mcpTools.includes(tool));
|
|
48765
49051
|
}
|
|
48766
49052
|
// src/lib/registry-sync.ts
|
|
48767
|
-
import { mkdirSync as
|
|
49053
|
+
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync13 } from "fs";
|
|
48768
49054
|
import { dirname as dirname30, relative as relative13 } from "path";
|
|
48769
49055
|
function createRegistrySyncArtifact(options = {}) {
|
|
48770
49056
|
const profile = options.profile ?? "all";
|
|
@@ -48822,7 +49108,7 @@ function createRegistrySyncArtifact(options = {}) {
|
|
|
48822
49108
|
};
|
|
48823
49109
|
}
|
|
48824
49110
|
function writeRegistrySyncArtifact(path, artifact) {
|
|
48825
|
-
|
|
49111
|
+
mkdirSync16(dirname30(path), { recursive: true });
|
|
48826
49112
|
writeFileSync13(path, `${JSON.stringify(artifact, null, 2)}
|
|
48827
49113
|
`);
|
|
48828
49114
|
}
|
|
@@ -49906,7 +50192,7 @@ function clone3(value) {
|
|
|
49906
50192
|
return JSON.parse(JSON.stringify(value));
|
|
49907
50193
|
}
|
|
49908
50194
|
// src/lib/feedback.ts
|
|
49909
|
-
import { appendFileSync, existsSync as existsSync19, mkdirSync as
|
|
50195
|
+
import { appendFileSync, existsSync as existsSync19, mkdirSync as mkdirSync17 } from "fs";
|
|
49910
50196
|
import { dirname as dirname31, join as join45 } from "path";
|
|
49911
50197
|
import { Database } from "bun:sqlite";
|
|
49912
50198
|
function getFeedbackDbPath() {
|
|
@@ -49916,7 +50202,7 @@ function getFeedbackDb() {
|
|
|
49916
50202
|
const dbPath = getFeedbackDbPath();
|
|
49917
50203
|
const dir = dirname31(dbPath);
|
|
49918
50204
|
if (!existsSync19(dir))
|
|
49919
|
-
|
|
50205
|
+
mkdirSync17(dir, { recursive: true });
|
|
49920
50206
|
const db = new Database(dbPath);
|
|
49921
50207
|
db.exec("PRAGMA journal_mode = WAL");
|
|
49922
50208
|
db.exec([
|
|
@@ -49945,7 +50231,7 @@ function saveFeedback(input2) {
|
|
|
49945
50231
|
const path = join45(getDataDir(), "feedback.jsonl");
|
|
49946
50232
|
const dir = dirname31(path);
|
|
49947
50233
|
if (!existsSync19(dir))
|
|
49948
|
-
|
|
50234
|
+
mkdirSync17(dir, { recursive: true });
|
|
49949
50235
|
appendFileSync(path, JSON.stringify({ message, category, email: input2.email ?? null, agent: input2.agent ?? null, version: input2.version ?? null, createdAt: new Date().toISOString() }) + `
|
|
49950
50236
|
`);
|
|
49951
50237
|
return { saved: true, category, path };
|
|
@@ -49969,9 +50255,9 @@ function isApiMode(env = process.env) {
|
|
|
49969
50255
|
import { createHash as createHash35, createHmac as createHmac2 } from "crypto";
|
|
49970
50256
|
import {
|
|
49971
50257
|
existsSync as existsSync20,
|
|
49972
|
-
mkdirSync as
|
|
50258
|
+
mkdirSync as mkdirSync18,
|
|
49973
50259
|
readFileSync as readFileSync31,
|
|
49974
|
-
readdirSync as
|
|
50260
|
+
readdirSync as readdirSync17,
|
|
49975
50261
|
statSync as statSync15,
|
|
49976
50262
|
writeFileSync as writeFileSync14
|
|
49977
50263
|
} from "fs";
|
|
@@ -50171,7 +50457,7 @@ function importSkillsLocalSnapshot(snapshot2, targetDir = process.cwd(), options
|
|
|
50171
50457
|
if (hash5 !== file2.sha256) {
|
|
50172
50458
|
throw new Error(`Snapshot file checksum mismatch: ${file2.path}`);
|
|
50173
50459
|
}
|
|
50174
|
-
|
|
50460
|
+
mkdirSync18(dirname32(absolutePath5), { recursive: true });
|
|
50175
50461
|
writeFileSync14(absolutePath5, bytes);
|
|
50176
50462
|
written += 1;
|
|
50177
50463
|
}
|
|
@@ -50468,7 +50754,7 @@ function parsePositiveInteger(value) {
|
|
|
50468
50754
|
}
|
|
50469
50755
|
function walkFiles2(dir) {
|
|
50470
50756
|
const files = [];
|
|
50471
|
-
for (const entry of
|
|
50757
|
+
for (const entry of readdirSync17(dir)) {
|
|
50472
50758
|
const full = join46(dir, entry);
|
|
50473
50759
|
const stats = statSync15(full);
|
|
50474
50760
|
if (stats.isDirectory())
|
|
@@ -50554,7 +50840,7 @@ function toArrayBuffer(bytes) {
|
|
|
50554
50840
|
import { createHash as createHash36 } from "crypto";
|
|
50555
50841
|
import {
|
|
50556
50842
|
copyFileSync,
|
|
50557
|
-
mkdirSync as
|
|
50843
|
+
mkdirSync as mkdirSync19,
|
|
50558
50844
|
readFileSync as readFileSync32,
|
|
50559
50845
|
statSync as statSync17,
|
|
50560
50846
|
writeFileSync as writeFileSync15
|
|
@@ -50562,7 +50848,7 @@ import {
|
|
|
50562
50848
|
import { dirname as dirname33, isAbsolute as isAbsolute31, relative as relative15, resolve as resolve30, sep as sep20 } from "path";
|
|
50563
50849
|
|
|
50564
50850
|
// src/lib/portable-snapshot-filter.ts
|
|
50565
|
-
import { readdirSync as
|
|
50851
|
+
import { readdirSync as readdirSync18, statSync as statSync16 } from "fs";
|
|
50566
50852
|
import { homedir as homedir7 } from "os";
|
|
50567
50853
|
import { join as join47, sep as sep19 } from "path";
|
|
50568
50854
|
var SYNC_HOMES = [
|
|
@@ -50671,7 +50957,7 @@ function destinationFor(definition, stationId, relativePath) {
|
|
|
50671
50957
|
function walkEntries(absoluteRoot) {
|
|
50672
50958
|
let entries;
|
|
50673
50959
|
try {
|
|
50674
|
-
entries =
|
|
50960
|
+
entries = readdirSync18(absoluteRoot, { withFileTypes: true });
|
|
50675
50961
|
} catch {
|
|
50676
50962
|
return [];
|
|
50677
50963
|
}
|
|
@@ -50847,7 +51133,7 @@ function writeStationSnapshot(options) {
|
|
|
50847
51133
|
let written = 0;
|
|
50848
51134
|
for (const plan of untouched) {
|
|
50849
51135
|
const destination = resolve30(repoRoot, plan.destination);
|
|
50850
|
-
|
|
51136
|
+
mkdirSync19(dirname33(destination), { recursive: true });
|
|
50851
51137
|
copyFileSync(plan.source.fullPath, destination);
|
|
50852
51138
|
written += 1;
|
|
50853
51139
|
}
|
|
@@ -50866,7 +51152,7 @@ function writeStationSnapshot(options) {
|
|
|
50866
51152
|
files: manifestFiles
|
|
50867
51153
|
};
|
|
50868
51154
|
const manifestPath = resolve30(repoRoot, "resources", options.stationId, "skills", "sync-manifest.json");
|
|
50869
|
-
|
|
51155
|
+
mkdirSync19(dirname33(manifestPath), { recursive: true });
|
|
50870
51156
|
writeFileSync15(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
50871
51157
|
`);
|
|
50872
51158
|
return {
|
|
@@ -50880,8 +51166,8 @@ function writeStationSnapshot(options) {
|
|
|
50880
51166
|
import { createHash as createHash37 } from "crypto";
|
|
50881
51167
|
import {
|
|
50882
51168
|
copyFileSync as copyFileSync2,
|
|
50883
|
-
mkdirSync as
|
|
50884
|
-
readdirSync as
|
|
51169
|
+
mkdirSync as mkdirSync20,
|
|
51170
|
+
readdirSync as readdirSync19,
|
|
50885
51171
|
readFileSync as readFileSync33,
|
|
50886
51172
|
statSync as statSync18,
|
|
50887
51173
|
writeFileSync as writeFileSync16
|
|
@@ -50928,7 +51214,7 @@ function planStationHydration(stationId, repoRoot) {
|
|
|
50928
51214
|
const agentRoot = join48(snapshotRoot, "agent-homes", agent);
|
|
50929
51215
|
let identEntries;
|
|
50930
51216
|
try {
|
|
50931
|
-
identEntries =
|
|
51217
|
+
identEntries = readdirSync19(agentRoot, { withFileTypes: true });
|
|
50932
51218
|
} catch {
|
|
50933
51219
|
continue;
|
|
50934
51220
|
}
|
|
@@ -51142,7 +51428,7 @@ function writeStationHydration(options) {
|
|
|
51142
51428
|
}
|
|
51143
51429
|
let written = 0;
|
|
51144
51430
|
for (const entry of toWrite) {
|
|
51145
|
-
|
|
51431
|
+
mkdirSync20(dirname34(entry.destination), { recursive: true });
|
|
51146
51432
|
copyFileSync2(entry.fullPath, entry.destination);
|
|
51147
51433
|
written += 1;
|
|
51148
51434
|
}
|
|
@@ -51164,7 +51450,7 @@ function writeStationHydration(options) {
|
|
|
51164
51450
|
skills: resultSkills
|
|
51165
51451
|
};
|
|
51166
51452
|
const hydrationManifestPath = join48(dirname34(cacheRoot), `hydration-${options.stationId}.json`);
|
|
51167
|
-
|
|
51453
|
+
mkdirSync20(dirname34(hydrationManifestPath), { recursive: true });
|
|
51168
51454
|
writeFileSync16(hydrationManifestPath, `${JSON.stringify(hydration, null, 2)}
|
|
51169
51455
|
`);
|
|
51170
51456
|
return {
|
|
@@ -51175,7 +51461,7 @@ function writeStationHydration(options) {
|
|
|
51175
51461
|
};
|
|
51176
51462
|
}
|
|
51177
51463
|
// src/lib/private-publication-recovery.ts
|
|
51178
|
-
import { constants as constants21, closeSync as closeSync20, fsyncSync as fsyncSync8, fstatSync as fstatSync20, lstatSync as lstatSync34, mkdirSync as
|
|
51464
|
+
import { constants as constants21, closeSync as closeSync20, fsyncSync as fsyncSync8, fstatSync as fstatSync20, lstatSync as lstatSync34, mkdirSync as mkdirSync21, openSync as openSync20, readSync as readSync15, realpathSync as realpathSync16, renameSync as renameSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync17 } from "fs";
|
|
51179
51465
|
import { dirname as dirname35, isAbsolute as isAbsolute32, join as join49, resolve as resolve32 } from "path";
|
|
51180
51466
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
51181
51467
|
var fail3 = () => {
|
|
@@ -51322,7 +51608,7 @@ async function preparePrivatePublication(client2, sourceDirectory, recoveryDirec
|
|
|
51322
51608
|
};
|
|
51323
51609
|
if (!isAbsolute32(recoveryDirectory) || resolve32(recoveryDirectory) !== recoveryDirectory || realpathSync16(dirname35(recoveryDirectory)) !== dirname35(recoveryDirectory))
|
|
51324
51610
|
return fail3();
|
|
51325
|
-
|
|
51611
|
+
mkdirSync21(recoveryDirectory, { mode: 448 });
|
|
51326
51612
|
safeDirectory(recoveryDirectory);
|
|
51327
51613
|
const parent = openSync20(dirname35(recoveryDirectory), constants21.O_RDONLY | constants21.O_NOFOLLOW);
|
|
51328
51614
|
try {
|
|
@@ -51646,7 +51932,7 @@ function applySessionReconciliation(snapshot2, target, planned, record12, verifi
|
|
|
51646
51932
|
}
|
|
51647
51933
|
// src/lib/claude-prospective-review.ts
|
|
51648
51934
|
import { createHash as createHash40 } from "crypto";
|
|
51649
|
-
import { lstatSync as lstatSync35, readFileSync as readFileSync34, readdirSync as
|
|
51935
|
+
import { lstatSync as lstatSync35, readFileSync as readFileSync34, readdirSync as readdirSync20, realpathSync as realpathSync17 } from "fs";
|
|
51650
51936
|
import { basename as basename18, dirname as dirname36, isAbsolute as isAbsolute33, join as join50, relative as relative16, resolve as resolve34, sep as sep22 } from "path";
|
|
51651
51937
|
var MAX_CANDIDATE_FILES = 16384;
|
|
51652
51938
|
var MAX_CANDIDATE_BYTES = 256 * 1024 * 1024;
|
|
@@ -51693,7 +51979,7 @@ function captureClaudeProspectiveCandidateClosure(root2) {
|
|
|
51693
51979
|
let bytes = 0;
|
|
51694
51980
|
const walk2 = (directory3) => {
|
|
51695
51981
|
const beforeDirectory = lstatSync35(directory3);
|
|
51696
|
-
const names =
|
|
51982
|
+
const names = readdirSync20(directory3).sort();
|
|
51697
51983
|
if (new Set(names).size !== names.length)
|
|
51698
51984
|
refuse6("candidate contains ambiguous directory entries");
|
|
51699
51985
|
for (const name of names) {
|