opencode-gitlab-dap 1.16.6 → 1.17.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/README.md +21 -0
- package/dist/index.cjs +120 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +120 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3891,7 +3891,16 @@ function searchSkillsSh(query) {
|
|
|
3891
3891
|
function downloadSkillFromSkillsSh(identifier) {
|
|
3892
3892
|
const tmp = mkdtempSync(join2(tmpdir(), "skill-install-"));
|
|
3893
3893
|
try {
|
|
3894
|
-
|
|
3894
|
+
const atIdx = identifier.indexOf("@");
|
|
3895
|
+
let cmd;
|
|
3896
|
+
if (atIdx !== -1) {
|
|
3897
|
+
const repo = identifier.slice(0, atIdx);
|
|
3898
|
+
const skill = identifier.slice(atIdx + 1);
|
|
3899
|
+
cmd = `npx skills add ${JSON.stringify(repo)} --skill ${JSON.stringify(skill)} -y --copy`;
|
|
3900
|
+
} else {
|
|
3901
|
+
cmd = `npx skills add ${JSON.stringify(identifier)} -y --copy`;
|
|
3902
|
+
}
|
|
3903
|
+
execSync(cmd, {
|
|
3895
3904
|
timeout: 6e4,
|
|
3896
3905
|
cwd: tmp,
|
|
3897
3906
|
encoding: "utf-8",
|
|
@@ -3944,6 +3953,73 @@ function downloadSkillFromSkillsSh(identifier) {
|
|
|
3944
3953
|
}
|
|
3945
3954
|
}
|
|
3946
3955
|
|
|
3956
|
+
// src/tools/skill-audit.ts
|
|
3957
|
+
var PROVIDER_NAMES = {
|
|
3958
|
+
"agent-trust-hub": "Gen Agent Trust Hub",
|
|
3959
|
+
socket: "Socket",
|
|
3960
|
+
snyk: "Snyk"
|
|
3961
|
+
};
|
|
3962
|
+
function parseIdentifierToUrl(identifier) {
|
|
3963
|
+
const atIdx = identifier.indexOf("@");
|
|
3964
|
+
if (atIdx === -1) return null;
|
|
3965
|
+
const ownerRepo = identifier.slice(0, atIdx);
|
|
3966
|
+
const skillName = identifier.slice(atIdx + 1);
|
|
3967
|
+
if (!ownerRepo.includes("/") || !skillName) return null;
|
|
3968
|
+
return `https://skills.sh/${ownerRepo}/${skillName}`;
|
|
3969
|
+
}
|
|
3970
|
+
function parseAuditHtml(html, auditUrl) {
|
|
3971
|
+
const secIdx = html.indexOf("Security Audits");
|
|
3972
|
+
if (secIdx === -1) return null;
|
|
3973
|
+
const section = html.slice(secIdx, secIdx + 5e3);
|
|
3974
|
+
const providerPattern = /href="[^"]*\/security\/(agent-trust-hub|socket|snyk)"[\s\S]*?>(Pass|Fail|Warn)</g;
|
|
3975
|
+
const results = [];
|
|
3976
|
+
let match;
|
|
3977
|
+
while ((match = providerPattern.exec(section)) !== null) {
|
|
3978
|
+
const slug = match[1];
|
|
3979
|
+
const status = match[2];
|
|
3980
|
+
results.push({
|
|
3981
|
+
provider: PROVIDER_NAMES[slug] ?? slug,
|
|
3982
|
+
status,
|
|
3983
|
+
detailUrl: `${auditUrl}/security/${slug}`
|
|
3984
|
+
});
|
|
3985
|
+
}
|
|
3986
|
+
if (results.length === 0) return null;
|
|
3987
|
+
return {
|
|
3988
|
+
results,
|
|
3989
|
+
hasFailure: results.some((r) => r.status === "Fail"),
|
|
3990
|
+
hasWarning: results.some((r) => r.status === "Warn"),
|
|
3991
|
+
auditUrl
|
|
3992
|
+
};
|
|
3993
|
+
}
|
|
3994
|
+
async function fetchSkillAudit(identifier) {
|
|
3995
|
+
const url = parseIdentifierToUrl(identifier);
|
|
3996
|
+
if (!url) return null;
|
|
3997
|
+
try {
|
|
3998
|
+
const resp = await fetch(url, {
|
|
3999
|
+
signal: AbortSignal.timeout(1e4),
|
|
4000
|
+
headers: { Accept: "text/html" }
|
|
4001
|
+
});
|
|
4002
|
+
if (!resp.ok) return null;
|
|
4003
|
+
const html = await resp.text();
|
|
4004
|
+
return parseAuditHtml(html, url);
|
|
4005
|
+
} catch {
|
|
4006
|
+
return null;
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
function formatAuditLine(audit) {
|
|
4010
|
+
return audit.results.map((r) => {
|
|
4011
|
+
const icon = r.status === "Fail" ? "\u{1F534}" : r.status === "Warn" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
4012
|
+
return `${icon} ${r.provider}: ${r.status}`;
|
|
4013
|
+
}).join(" | ");
|
|
4014
|
+
}
|
|
4015
|
+
function formatAuditRate(audit) {
|
|
4016
|
+
const total = audit.results.length;
|
|
4017
|
+
const passed = audit.results.filter((r) => r.status === "Pass").length;
|
|
4018
|
+
if (passed === total) return `Security: ${passed}/${total} audits passed \u2705`;
|
|
4019
|
+
if (audit.hasFailure) return `Security: ${passed}/${total} audits passed \u274C`;
|
|
4020
|
+
return `Security: ${passed}/${total} audits passed \u26A0\uFE0F`;
|
|
4021
|
+
}
|
|
4022
|
+
|
|
3947
4023
|
// src/tools/skill-tools.ts
|
|
3948
4024
|
var z6 = tool6.schema;
|
|
3949
4025
|
var PROJECT_ID_DESC2 = "Project path from git remote";
|
|
@@ -4228,14 +4304,32 @@ Install: \`gitlab_skill_install(name="${e.name}", source="group", group_id="${ar
|
|
|
4228
4304
|
}
|
|
4229
4305
|
const shResults = searchSkillsSh(args.query);
|
|
4230
4306
|
if (shResults.length > 0) {
|
|
4307
|
+
const audits = await Promise.all(shResults.map((r) => fetchSkillAudit(r.identifier)));
|
|
4231
4308
|
sections.push(
|
|
4232
4309
|
`### skills.sh (${shResults.length})
|
|
4233
4310
|
|
|
4234
|
-
` + shResults.map(
|
|
4235
|
-
|
|
4311
|
+
` + shResults.map((r, i) => {
|
|
4312
|
+
const audit = audits[i];
|
|
4313
|
+
let line = `**${r.identifier}** (${r.installs})`;
|
|
4314
|
+
if (audit) {
|
|
4315
|
+
line += `
|
|
4316
|
+
${formatAuditRate(audit)}`;
|
|
4317
|
+
line += `
|
|
4318
|
+
${formatAuditLine(audit)}`;
|
|
4319
|
+
if (audit.hasFailure) {
|
|
4320
|
+
line += `
|
|
4321
|
+
\u26D4 BLOCKED \u2014 security audit failures detected. Review: ${audit.auditUrl}`;
|
|
4322
|
+
return line;
|
|
4323
|
+
}
|
|
4324
|
+
} else {
|
|
4325
|
+
line += `
|
|
4326
|
+
Security: unknown (audit data unavailable)`;
|
|
4327
|
+
}
|
|
4328
|
+
line += `
|
|
4236
4329
|
${r.url}
|
|
4237
|
-
Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")
|
|
4238
|
-
|
|
4330
|
+
Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``;
|
|
4331
|
+
return line;
|
|
4332
|
+
}).join("\n\n")
|
|
4239
4333
|
);
|
|
4240
4334
|
}
|
|
4241
4335
|
if (sections.length === 0) {
|
|
@@ -4258,6 +4352,14 @@ Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``
|
|
|
4258
4352
|
const projectScope = resolveScope2(args);
|
|
4259
4353
|
const targetPrefix = args.draft ? DRAFTS_PREFIX : SKILLS_PREFIX;
|
|
4260
4354
|
if (args.source === "skills.sh") {
|
|
4355
|
+
const audit = await fetchSkillAudit(args.name);
|
|
4356
|
+
if (audit?.hasFailure) {
|
|
4357
|
+
const failures = audit.results.filter((r) => r.status === "Fail").map((r) => ` \u{1F534} ${r.provider}: Fail (${r.detailUrl})`).join("\n");
|
|
4358
|
+
return `\u26D4 Installation BLOCKED \u2014 security audit failure(s) detected:
|
|
4359
|
+
${failures}
|
|
4360
|
+
|
|
4361
|
+
Review the audit details before proceeding: ${audit.auditUrl}`;
|
|
4362
|
+
}
|
|
4261
4363
|
const downloaded = downloadSkillFromSkillsSh(args.name);
|
|
4262
4364
|
if (!downloaded) {
|
|
4263
4365
|
return `Failed to download skill "${args.name}" from skills.sh.`;
|
|
@@ -4309,7 +4411,19 @@ Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``
|
|
|
4309
4411
|
}
|
|
4310
4412
|
const parts = [`${wikiCount} wiki page(s)`];
|
|
4311
4413
|
if (hasBundle) parts.push(`${scriptFiles.length} bundled script(s)`);
|
|
4312
|
-
|
|
4414
|
+
let result = `Installed skill "${downloaded.name}" from skills.sh. ${parts.join(", ")}. Use gitlab_skill_setup to extract scripts.`;
|
|
4415
|
+
if (audit?.hasWarning) {
|
|
4416
|
+
const warnings = audit.results.filter((r) => r.status === "Warn").map((r) => ` \u26A0\uFE0F ${r.provider}: Warn (${r.detailUrl})`).join("\n");
|
|
4417
|
+
result += `
|
|
4418
|
+
|
|
4419
|
+
\u26A0\uFE0F Security audit warnings:
|
|
4420
|
+
${warnings}`;
|
|
4421
|
+
} else if (!audit) {
|
|
4422
|
+
result += `
|
|
4423
|
+
|
|
4424
|
+
(security audit data unavailable \u2014 skills.sh may be unreachable)`;
|
|
4425
|
+
}
|
|
4426
|
+
return result;
|
|
4313
4427
|
} catch (err) {
|
|
4314
4428
|
return `Error installing from skills.sh: ${err.message}`;
|
|
4315
4429
|
}
|