bazilion 0.7.0 → 0.8.0
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/cli.js +80 -17
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +143 -23
- package/dist/daemon.js.map +1 -1
- package/dist/web/client/assets/{TemplatesTabs-Da7mg9FI.js → TemplatesTabs-UM04RMO9.js} +1 -1
- package/dist/web/client/assets/{_id-LT6Ejjr0.js → _id-BNJapCT4.js} +1 -1
- package/dist/web/client/assets/{_id-_6jIt0_-.js → _id-CjGoV8Mr.js} +1 -1
- package/dist/web/client/assets/{_id-BdKmo0gb.js → _id-DehuCHUw.js} +1 -1
- package/dist/web/client/assets/{_id-MR2XjWh0.js → _id-Dz9fjcCM.js} +1 -1
- package/dist/web/client/assets/{agents-0arKbVYG.js → agents-M6omAXcZ.js} +1 -1
- package/dist/web/client/assets/{config-BSAVT-17.js → config-DIuEc5bm.js} +1 -1
- package/dist/web/client/assets/{groups-BqTkhHes.js → groups-DpE2d2zZ.js} +1 -1
- package/dist/web/client/assets/{inbox-ozoCXzr5.js → inbox-BPnLsRNf.js} +1 -1
- package/dist/web/client/assets/{index-iayCEuU2.js → index-MAJuXnie.js} +2 -2
- package/dist/web/client/assets/{login-D8lNr2SX.js → login-CawJX16E.js} +1 -1
- package/dist/web/client/assets/{mcp-BLnngDsj.js → mcp-DIrh9-v_.js} +1 -1
- package/dist/web/client/assets/{memory-D1GQjEvN.js → memory-BpHbdKsd.js} +1 -1
- package/dist/web/client/assets/{profile-groups-C2yJPTaE.js → profile-groups-ByoKak0c.js} +1 -1
- package/dist/web/client/assets/{profiles-BV7AAZjj.js → profiles-BEjv8LGo.js} +1 -1
- package/dist/web/client/assets/{routes-DSHQLA7K.js → routes-D2COHy7v.js} +1 -1
- package/dist/web/client/assets/{services-BbCJe1Du.js → services-D212jSK_.js} +1 -1
- package/dist/web/client/assets/skills-Da0MURjY.js +1 -0
- package/dist/web/client/assets/styles-BgE5bCHA.css +2 -0
- package/dist/web/client/assets/{telegram-gE4j8gte.js → telegram-Czh2MdVm.js} +1 -1
- package/dist/web/client/assets/{tokens-D2_O9ARe.js → tokens-E_JvO5JN.js} +1 -1
- package/dist/web/client/assets/{triggers-WljnfEfJ.js → triggers-BBRZQOm7.js} +1 -1
- package/dist/web/server/assets/{_id-D0ytyXGY.js → _id-BdRiQb2H.js} +42 -5
- package/dist/web/server/assets/{_id-81NrHA5d.js → _id-DUIrFV3G.js} +1 -1
- package/dist/web/server/assets/{_tanstack-start-manifest_v-DBlFH2gg.js → _tanstack-start-manifest_v-D9FLKShQ.js} +23 -23
- package/dist/web/server/assets/{router-BpBZgRwn.js → router-BrDascdO.js} +3 -3
- package/dist/web/server/assets/{skills-dLyBZb3B.js → skills-D89ND2kR.js} +67 -7
- package/dist/web/server/assets/{skills-CpsyR_WA.js → skills-l2cyQ3zS.js} +1 -1
- package/dist/web/server/server.js +2 -2
- package/dist/worker.js.map +1 -1
- package/package.json +3 -3
- package/dist/web/client/assets/skills-C6czKR5I.js +0 -1
- package/dist/web/client/assets/styles-C06axZZk.css +0 -2
package/dist/daemon.js
CHANGED
|
@@ -12518,11 +12518,11 @@ var require_util = __commonJS({
|
|
|
12518
12518
|
return false;
|
|
12519
12519
|
}
|
|
12520
12520
|
exports.schemaHasRules = schemaHasRules;
|
|
12521
|
-
function schemaHasRulesButRef(schema,
|
|
12521
|
+
function schemaHasRulesButRef(schema, RULES2) {
|
|
12522
12522
|
if (typeof schema == "boolean")
|
|
12523
12523
|
return !schema;
|
|
12524
12524
|
for (const key2 in schema)
|
|
12525
|
-
if (key2 !== "$ref" &&
|
|
12525
|
+
if (key2 !== "$ref" && RULES2.all[key2])
|
|
12526
12526
|
return true;
|
|
12527
12527
|
return false;
|
|
12528
12528
|
}
|
|
@@ -13916,17 +13916,17 @@ var require_validate = __commonJS({
|
|
|
13916
13916
|
}
|
|
13917
13917
|
function schemaKeywords(it, types, typeErrors, errsCount) {
|
|
13918
13918
|
const { gen, schema, data, allErrors, opts, self } = it;
|
|
13919
|
-
const { RULES } = self;
|
|
13920
|
-
if (schema.$ref && (opts.ignoreKeywordsWithRef || !(0, util_1.schemaHasRulesButRef)(schema,
|
|
13921
|
-
gen.block(() => keywordCode(it, "$ref",
|
|
13919
|
+
const { RULES: RULES2 } = self;
|
|
13920
|
+
if (schema.$ref && (opts.ignoreKeywordsWithRef || !(0, util_1.schemaHasRulesButRef)(schema, RULES2))) {
|
|
13921
|
+
gen.block(() => keywordCode(it, "$ref", RULES2.all.$ref.definition));
|
|
13922
13922
|
return;
|
|
13923
13923
|
}
|
|
13924
13924
|
if (!opts.jtd)
|
|
13925
13925
|
checkStrictTypes(it, types);
|
|
13926
13926
|
gen.block(() => {
|
|
13927
|
-
for (const group of
|
|
13927
|
+
for (const group of RULES2.rules)
|
|
13928
13928
|
groupKeywords(group);
|
|
13929
|
-
groupKeywords(
|
|
13929
|
+
groupKeywords(RULES2.post);
|
|
13930
13930
|
});
|
|
13931
13931
|
function groupKeywords(group) {
|
|
13932
13932
|
if (!(0, applicability_1.shouldUseGroup)(schema, group))
|
|
@@ -15715,10 +15715,10 @@ var require_core = __commonJS({
|
|
|
15715
15715
|
}
|
|
15716
15716
|
// Remove keyword
|
|
15717
15717
|
removeKeyword(keyword) {
|
|
15718
|
-
const { RULES } = this;
|
|
15719
|
-
delete
|
|
15720
|
-
delete
|
|
15721
|
-
for (const group of
|
|
15718
|
+
const { RULES: RULES2 } = this;
|
|
15719
|
+
delete RULES2.keywords[keyword];
|
|
15720
|
+
delete RULES2.all[keyword];
|
|
15721
|
+
for (const group of RULES2.rules) {
|
|
15722
15722
|
const i = group.rules.findIndex((rule) => rule.keyword === keyword);
|
|
15723
15723
|
if (i >= 0)
|
|
15724
15724
|
group.rules.splice(i, 1);
|
|
@@ -15886,9 +15886,9 @@ var require_core = __commonJS({
|
|
|
15886
15886
|
}
|
|
15887
15887
|
var KEYWORD_NAME = /^[a-z_$][a-z0-9_$:-]*$/i;
|
|
15888
15888
|
function checkKeyword(keyword, def) {
|
|
15889
|
-
const { RULES } = this;
|
|
15889
|
+
const { RULES: RULES2 } = this;
|
|
15890
15890
|
(0, util_1.eachItem)(keyword, (kwd) => {
|
|
15891
|
-
if (
|
|
15891
|
+
if (RULES2.keywords[kwd])
|
|
15892
15892
|
throw new Error(`Keyword ${kwd} is already defined`);
|
|
15893
15893
|
if (!KEYWORD_NAME.test(kwd))
|
|
15894
15894
|
throw new Error(`Keyword ${kwd} has invalid name`);
|
|
@@ -15904,13 +15904,13 @@ var require_core = __commonJS({
|
|
|
15904
15904
|
const post = definition === null || definition === void 0 ? void 0 : definition.post;
|
|
15905
15905
|
if (dataType && post)
|
|
15906
15906
|
throw new Error('keyword with "post" flag cannot have "type"');
|
|
15907
|
-
const { RULES } = this;
|
|
15908
|
-
let ruleGroup = post ?
|
|
15907
|
+
const { RULES: RULES2 } = this;
|
|
15908
|
+
let ruleGroup = post ? RULES2.post : RULES2.rules.find(({ type: t }) => t === dataType);
|
|
15909
15909
|
if (!ruleGroup) {
|
|
15910
15910
|
ruleGroup = { type: dataType, rules: [] };
|
|
15911
|
-
|
|
15911
|
+
RULES2.rules.push(ruleGroup);
|
|
15912
15912
|
}
|
|
15913
|
-
|
|
15913
|
+
RULES2.keywords[keyword] = true;
|
|
15914
15914
|
if (!definition)
|
|
15915
15915
|
return;
|
|
15916
15916
|
const rule = {
|
|
@@ -15925,7 +15925,7 @@ var require_core = __commonJS({
|
|
|
15925
15925
|
addBeforeRule.call(this, ruleGroup, rule, definition.before);
|
|
15926
15926
|
else
|
|
15927
15927
|
ruleGroup.rules.push(rule);
|
|
15928
|
-
|
|
15928
|
+
RULES2.all[keyword] = rule;
|
|
15929
15929
|
(_a3 = definition.implements) === null || _a3 === void 0 ? void 0 : _a3.forEach((kwd) => this.addKeyword(kwd));
|
|
15930
15930
|
}
|
|
15931
15931
|
function addBeforeRule(ruleGroup, rule, before) {
|
|
@@ -21738,7 +21738,74 @@ function parseSkillFile(path) {
|
|
|
21738
21738
|
return parseSkillContent(raw);
|
|
21739
21739
|
}
|
|
21740
21740
|
|
|
21741
|
+
// ../daemon/src/core/skills/scan.ts
|
|
21742
|
+
var SECRET_ENV_RE = /\b(ANTHROPIC_API_KEY|OPENAI_API_KEY|OPENAI_CODEX_OAUTH|GEMINI_API_KEY|GOOGLE_API_KEY|AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|AZURE_OPENAI_API_KEY|MISTRAL_API_KEY|GROQ_API_KEY|BRAVE_API_KEY|SEARXNG_URL)\b/i;
|
|
21743
|
+
var SENSITIVE_PATH_RE = /(~\/\.(ssh|aws|gnupg|config)|\b(auth\.json|bazilion\.db)\b)/i;
|
|
21744
|
+
var SECRET_TARGET_RE = /(secret|credential|token|api[-_\s]?key|env(?:ironment)?(?: variable)?|private key|ssh key|auth\.json|bazilion\.db|~\/\.(ssh|aws|gnupg))/i;
|
|
21745
|
+
var EXFIL_VERB_RE = /(exfiltrat|send|upload|post|curl|webhook|pastebin|remote server|external server|http endpoint)/i;
|
|
21746
|
+
var UNICODE_STEALTH_RE = /[\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFEFF]/;
|
|
21747
|
+
var RULES = [
|
|
21748
|
+
{
|
|
21749
|
+
code: "sensitive-reference",
|
|
21750
|
+
severity: "danger",
|
|
21751
|
+
message: "Mentions a sensitive path, database, auth file, or credential environment variable.",
|
|
21752
|
+
test: (line) => SENSITIVE_PATH_RE.test(line) || SECRET_ENV_RE.test(line)
|
|
21753
|
+
},
|
|
21754
|
+
{
|
|
21755
|
+
code: "secret-exfiltration",
|
|
21756
|
+
severity: "danger",
|
|
21757
|
+
message: "Combines secret/env/file access with exfiltration-style language.",
|
|
21758
|
+
test: (line) => SECRET_TARGET_RE.test(line) && EXFIL_VERB_RE.test(line)
|
|
21759
|
+
},
|
|
21760
|
+
{
|
|
21761
|
+
code: "instruction-hijack",
|
|
21762
|
+
severity: "danger",
|
|
21763
|
+
message: "Contains instruction-hijacking language such as ignoring prior instructions.",
|
|
21764
|
+
test: (line) => /ignore (all )?(previous|prior|system|developer|user) instructions/i.test(line) || /override (the )?(system|developer) (prompt|instructions)/i.test(line) || /bypass (safety|security|policy|guardrails)/i.test(line) || /you are now (root|unrestricted|in developer mode)/i.test(line)
|
|
21765
|
+
},
|
|
21766
|
+
{
|
|
21767
|
+
code: "unicode-stealth",
|
|
21768
|
+
severity: "warning",
|
|
21769
|
+
message: "Contains zero-width, bidi, or byte-order characters that can hide prompt text.",
|
|
21770
|
+
test: (line) => UNICODE_STEALTH_RE.test(line)
|
|
21771
|
+
}
|
|
21772
|
+
];
|
|
21773
|
+
function addFinding(findings, seen, finding) {
|
|
21774
|
+
const key2 = `${finding.code}:${finding.line ?? 0}`;
|
|
21775
|
+
if (seen.has(key2)) return;
|
|
21776
|
+
seen.add(key2);
|
|
21777
|
+
findings.push(finding);
|
|
21778
|
+
}
|
|
21779
|
+
function scanSkillContent(raw) {
|
|
21780
|
+
const findings = [];
|
|
21781
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21782
|
+
const lines = raw.split(/\r?\n/);
|
|
21783
|
+
lines.forEach((line, index) => {
|
|
21784
|
+
for (const rule of RULES) {
|
|
21785
|
+
if (!rule.test(line)) continue;
|
|
21786
|
+
addFinding(findings, seen, {
|
|
21787
|
+
code: rule.code,
|
|
21788
|
+
severity: rule.severity,
|
|
21789
|
+
message: rule.message,
|
|
21790
|
+
line: index + 1
|
|
21791
|
+
});
|
|
21792
|
+
}
|
|
21793
|
+
});
|
|
21794
|
+
return findings;
|
|
21795
|
+
}
|
|
21796
|
+
|
|
21741
21797
|
// ../daemon/src/core/skills/import.ts
|
|
21798
|
+
var SkillScanBlockedError = class extends Error {
|
|
21799
|
+
findings;
|
|
21800
|
+
constructor(findings) {
|
|
21801
|
+
const names = Object.keys(findings).sort();
|
|
21802
|
+
super(
|
|
21803
|
+
`skill scan blocked import: ${names.join(", ")} ${names.length === 1 ? "has" : "have"} findings (rerun with --force to confirm)`
|
|
21804
|
+
);
|
|
21805
|
+
this.name = "SkillScanBlockedError";
|
|
21806
|
+
this.findings = findings;
|
|
21807
|
+
}
|
|
21808
|
+
};
|
|
21742
21809
|
function extractZipSafely(zipPath) {
|
|
21743
21810
|
const root = mkdtempSync(join10(tmpdir(), "bazilion-skill-zip-"));
|
|
21744
21811
|
try {
|
|
@@ -21805,8 +21872,14 @@ function importSkillsFromDir(paths, source, input) {
|
|
|
21805
21872
|
if (candidates.length === 0) {
|
|
21806
21873
|
throw new Error(`no skills found in ${source}`);
|
|
21807
21874
|
}
|
|
21875
|
+
const findingsBySkill = {};
|
|
21808
21876
|
for (const c of candidates) {
|
|
21809
|
-
parseSkillFile(join10(c.dir, "SKILL.md"));
|
|
21877
|
+
const parsed = parseSkillFile(join10(c.dir, "SKILL.md"));
|
|
21878
|
+
const findings = scanSkillContent(parsed.raw);
|
|
21879
|
+
if (findings.length > 0) findingsBySkill[c.name] = findings;
|
|
21880
|
+
}
|
|
21881
|
+
if (Object.keys(findingsBySkill).length > 0 && !input.force) {
|
|
21882
|
+
throw new SkillScanBlockedError(findingsBySkill);
|
|
21810
21883
|
}
|
|
21811
21884
|
const imported = [];
|
|
21812
21885
|
const skipped = [];
|
|
@@ -21815,14 +21888,19 @@ function importSkillsFromDir(paths, source, input) {
|
|
|
21815
21888
|
if (existsSync8(target) && !input.force) {
|
|
21816
21889
|
skipped.push({
|
|
21817
21890
|
name: c.name,
|
|
21818
|
-
reason: "already exists (use --force to overwrite)"
|
|
21891
|
+
reason: "already exists (use --force to overwrite)",
|
|
21892
|
+
findings: findingsBySkill[c.name]
|
|
21819
21893
|
});
|
|
21820
21894
|
continue;
|
|
21821
21895
|
}
|
|
21822
21896
|
cpSync(c.dir, target, { recursive: true, force: !!input.force });
|
|
21823
21897
|
imported.push(c.name);
|
|
21824
21898
|
}
|
|
21825
|
-
return {
|
|
21899
|
+
return {
|
|
21900
|
+
imported,
|
|
21901
|
+
skipped,
|
|
21902
|
+
findings: Object.keys(findingsBySkill).length > 0 ? findingsBySkill : void 0
|
|
21903
|
+
};
|
|
21826
21904
|
}
|
|
21827
21905
|
|
|
21828
21906
|
// ../daemon/src/core/skills/resolve.ts
|
|
@@ -29958,7 +30036,8 @@ agentsRouter.get("/:id/skills", (c) => {
|
|
|
29958
30036
|
name: s.name,
|
|
29959
30037
|
description: s.parsed.frontmatter.description,
|
|
29960
30038
|
source: meta2?.source ?? null,
|
|
29961
|
-
importedAt: meta2?.importedAt ?? null
|
|
30039
|
+
importedAt: meta2?.importedAt ?? null,
|
|
30040
|
+
scanFindings: scanSkillContent(s.parsed.raw)
|
|
29962
30041
|
};
|
|
29963
30042
|
}),
|
|
29964
30043
|
missing: set.missing
|
|
@@ -29973,6 +30052,24 @@ agentsRouter.post("/:id/skills", async (c) => {
|
|
|
29973
30052
|
const { db, paths, authToken } = getCtx();
|
|
29974
30053
|
const agent = agents_exports.get(db, c.req.param("id"));
|
|
29975
30054
|
if (!agent) return c.json({ error: `agent not found: ${c.req.param("id")}` }, 404);
|
|
30055
|
+
const discovered = discoverSkills(paths).find((s) => s.name === body.skill);
|
|
30056
|
+
if (discovered) {
|
|
30057
|
+
try {
|
|
30058
|
+
const parsed = parseSkillFile(discovered.skillFile);
|
|
30059
|
+
const findings = scanSkillContent(parsed.raw);
|
|
30060
|
+
if (findings.length > 0 && !body.allowFindings) {
|
|
30061
|
+
return c.json(
|
|
30062
|
+
{
|
|
30063
|
+
error: `skill scan blocked attach: ${body.skill} has findings`,
|
|
30064
|
+
code: "skill_scan_blocked",
|
|
30065
|
+
findings
|
|
30066
|
+
},
|
|
30067
|
+
400
|
|
30068
|
+
);
|
|
30069
|
+
}
|
|
30070
|
+
} catch {
|
|
30071
|
+
}
|
|
30072
|
+
}
|
|
29976
30073
|
agents_exports.attachSkill(db, agent.id, body.skill);
|
|
29977
30074
|
return c.body(null, 204);
|
|
29978
30075
|
});
|
|
@@ -31491,6 +31588,7 @@ skillsRouter.get("/", (c) => {
|
|
|
31491
31588
|
try {
|
|
31492
31589
|
const parsed = parseSkillFile(s.skillFile);
|
|
31493
31590
|
entry.description = parsed.frontmatter.description;
|
|
31591
|
+
entry.scanFindings = scanSkillContent(parsed.raw);
|
|
31494
31592
|
} catch (err) {
|
|
31495
31593
|
entry.parseError = err.message;
|
|
31496
31594
|
}
|
|
@@ -31521,14 +31619,36 @@ skillsRouter.post("/import", async (c) => {
|
|
|
31521
31619
|
for (const name of result.imported) {
|
|
31522
31620
|
skillMeta_exports.upsert(db, { name, source: input.sourceLabel, importedAt: now });
|
|
31523
31621
|
}
|
|
31524
|
-
const res = {
|
|
31622
|
+
const res = {
|
|
31623
|
+
imported: result.imported,
|
|
31624
|
+
skipped: result.skipped,
|
|
31625
|
+
findings: result.findings
|
|
31626
|
+
};
|
|
31525
31627
|
return c.json(res);
|
|
31526
31628
|
} catch (err) {
|
|
31629
|
+
if (err instanceof SkillScanBlockedError) {
|
|
31630
|
+
return c.json(
|
|
31631
|
+
{
|
|
31632
|
+
error: err.message,
|
|
31633
|
+
code: "skill_scan_blocked",
|
|
31634
|
+
findings: flattenFindings(err.findings)
|
|
31635
|
+
},
|
|
31636
|
+
400
|
|
31637
|
+
);
|
|
31638
|
+
}
|
|
31527
31639
|
return c.json({ error: err.message }, 400);
|
|
31528
31640
|
} finally {
|
|
31529
31641
|
if (input.tempZipPath) rmSync10(input.tempZipPath, { recursive: true, force: true });
|
|
31530
31642
|
}
|
|
31531
31643
|
});
|
|
31644
|
+
function flattenFindings(findings) {
|
|
31645
|
+
return Object.entries(findings).flatMap(
|
|
31646
|
+
([name, items]) => items.map((item) => ({
|
|
31647
|
+
...item,
|
|
31648
|
+
message: `${name}: ${item.message}`
|
|
31649
|
+
}))
|
|
31650
|
+
);
|
|
31651
|
+
}
|
|
31532
31652
|
async function parseImportInput(request) {
|
|
31533
31653
|
const contentType = request.headers.get("content-type") ?? "";
|
|
31534
31654
|
if (contentType.startsWith("multipart/form-data")) {
|