@synkro-sh/cli 1.7.44 → 1.7.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap.js +38 -15
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -4826,7 +4826,7 @@ function writeConfigEnv(opts) {
|
|
|
4826
4826
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
4827
4827
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
4828
4828
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
4829
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.7.
|
|
4829
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.7.46")}`
|
|
4830
4830
|
];
|
|
4831
4831
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
4832
4832
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -6106,7 +6106,10 @@ async function syncSkillFiles() {
|
|
|
6106
6106
|
console.log(` indexing ${tasks.length} skill file${tasks.length === 1 ? "" : "s"} \u2014 comparing against existing ruleset (this may take a few seconds)...`);
|
|
6107
6107
|
await ingestSkillTasks(tasks, mcpPort);
|
|
6108
6108
|
}
|
|
6109
|
-
function
|
|
6109
|
+
function normSkillName(name) {
|
|
6110
|
+
return name.toLowerCase().replace(/\.mdx?$/, "");
|
|
6111
|
+
}
|
|
6112
|
+
function discoverSkillFiles(repoRoot, excludeHashes, ingestedHashes, ingestedNames) {
|
|
6110
6113
|
const roots = [];
|
|
6111
6114
|
const add = (p) => {
|
|
6112
6115
|
try {
|
|
@@ -6135,9 +6138,10 @@ function discoverSkillFiles(repoRoot, excludeHashes, excludeNames) {
|
|
|
6135
6138
|
}
|
|
6136
6139
|
if (!content.trim()) return;
|
|
6137
6140
|
const hash = createHash("sha256").update(content).digest("hex");
|
|
6138
|
-
if (seen.has(hash) || excludeHashes.has(hash)
|
|
6141
|
+
if (seen.has(hash) || excludeHashes.has(hash)) return;
|
|
6139
6142
|
seen.add(hash);
|
|
6140
|
-
|
|
6143
|
+
const ingested = ingestedHashes.has(hash) || ingestedNames.has(normSkillName(name));
|
|
6144
|
+
out.push({ source: `skill:${name}`, content, name, hash, ingested });
|
|
6141
6145
|
};
|
|
6142
6146
|
for (const root of roots) {
|
|
6143
6147
|
let entries = [];
|
|
@@ -6170,19 +6174,29 @@ function discoverySetHash(found) {
|
|
|
6170
6174
|
}
|
|
6171
6175
|
async function promptSkillDiscovery(found) {
|
|
6172
6176
|
if (!process.stdin.isTTY || found.length === 0) return [];
|
|
6177
|
+
const selectableIdx = found.map((s, i) => s.ingested ? -1 : i).filter((i) => i >= 0);
|
|
6178
|
+
if (selectableIdx.length === 0) return [];
|
|
6173
6179
|
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
6174
6180
|
const ask3 = (q) => new Promise((res) => rl.question(q, (a) => res(a.trim())));
|
|
6175
6181
|
try {
|
|
6176
6182
|
console.log(`
|
|
6177
6183
|
Found ${found.length} skill${found.length === 1 ? "" : "s"} in your Claude Code / skills.sh folders:`);
|
|
6178
|
-
found.forEach((s, i) => console.log(` ${i + 1}. ${s.name}`));
|
|
6179
|
-
console.log("Ingest
|
|
6184
|
+
found.forEach((s, i) => console.log(` ${i + 1}. ${s.name}${s.ingested ? " \u2014 already ingested (not selectable)" : ""}`));
|
|
6185
|
+
console.log("Ingest the uningested skills as enforceable rules? Each is security-vetted first \u2014 anything");
|
|
6180
6186
|
console.log("malicious (prompt injection, guardrail-weakening, secret exfil) is blocked and reported.");
|
|
6181
|
-
const a = (await ask3(
|
|
6187
|
+
const a = (await ask3(`Ingest [all] (${selectableIdx.length} uningested) / type numbers (e.g. 1,3) / [skip]: `)).toLowerCase();
|
|
6182
6188
|
if (a === "skip" || a === "n" || a === "no" || a === "s") return [];
|
|
6183
|
-
if (a === "" || a === "all" || a === "y" || a === "yes" || a === "a") return
|
|
6189
|
+
if (a === "" || a === "all" || a === "y" || a === "yes" || a === "a") return selectableIdx;
|
|
6184
6190
|
const picks = a.split(/[\s,]+/).map((x) => parseInt(x, 10) - 1).filter((i) => Number.isInteger(i) && i >= 0 && i < found.length);
|
|
6185
|
-
|
|
6191
|
+
const valid = [];
|
|
6192
|
+
for (const i of [...new Set(picks)]) {
|
|
6193
|
+
if (found[i].ingested) {
|
|
6194
|
+
console.log(` \xB7 ${found[i].name} is already ingested \u2014 skipped`);
|
|
6195
|
+
continue;
|
|
6196
|
+
}
|
|
6197
|
+
valid.push(i);
|
|
6198
|
+
}
|
|
6199
|
+
return valid;
|
|
6186
6200
|
} finally {
|
|
6187
6201
|
rl.close();
|
|
6188
6202
|
}
|
|
@@ -6201,21 +6215,30 @@ async function discoverAndIngestSkills() {
|
|
|
6201
6215
|
}
|
|
6202
6216
|
}
|
|
6203
6217
|
}
|
|
6204
|
-
const
|
|
6218
|
+
const ingestedHashes = /* @__PURE__ */ new Set();
|
|
6219
|
+
const ingestedNames = /* @__PURE__ */ new Set();
|
|
6205
6220
|
try {
|
|
6206
6221
|
const resp = await fetch(`http://127.0.0.1:${mcpPort}/api/local/skills?status=active`, { signal: AbortSignal.timeout(5e3) });
|
|
6207
6222
|
if (resp.ok) {
|
|
6208
6223
|
const { skills } = await resp.json();
|
|
6209
6224
|
for (const s of skills || []) {
|
|
6210
|
-
if (s.content_hash)
|
|
6211
|
-
|
|
6225
|
+
if (s.content_hash) ingestedHashes.add(s.content_hash);
|
|
6226
|
+
if (s.name) ingestedNames.add(normSkillName(String(s.name)));
|
|
6212
6227
|
}
|
|
6213
6228
|
}
|
|
6214
6229
|
} catch {
|
|
6215
6230
|
}
|
|
6216
|
-
const found = discoverSkillFiles(repoRoot, excludeHashes,
|
|
6231
|
+
const found = discoverSkillFiles(repoRoot, excludeHashes, ingestedHashes, ingestedNames);
|
|
6217
6232
|
if (found.length === 0) return;
|
|
6218
|
-
const
|
|
6233
|
+
const selectable = found.filter((f) => !f.ingested);
|
|
6234
|
+
if (selectable.length === 0) {
|
|
6235
|
+
const names = found.map((f) => f.name);
|
|
6236
|
+
const shown = names.slice(0, 5).join(", ") + (names.length > 5 ? `, +${names.length - 5} more` : "");
|
|
6237
|
+
console.log(`
|
|
6238
|
+
\u2713 ${found.length} skill${found.length === 1 ? "" : "s"} already ingested (${shown}) \u2014 nothing new to add.`);
|
|
6239
|
+
return;
|
|
6240
|
+
}
|
|
6241
|
+
const setHash = discoverySetHash(selectable);
|
|
6219
6242
|
let prev = "";
|
|
6220
6243
|
try {
|
|
6221
6244
|
prev = readFileSync11(SKILLS_DISCOVERED_PATH, "utf-8").trim();
|
|
@@ -9055,7 +9078,7 @@ var args = process.argv.slice(2);
|
|
|
9055
9078
|
var cmd = args[0] || "";
|
|
9056
9079
|
var subArgs = args.slice(1);
|
|
9057
9080
|
function printVersion() {
|
|
9058
|
-
console.log("1.7.
|
|
9081
|
+
console.log("1.7.46");
|
|
9059
9082
|
}
|
|
9060
9083
|
function printHelp2() {
|
|
9061
9084
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|