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/README.md
CHANGED
|
@@ -279,6 +279,27 @@ Say **"bootstrap project memory"** to automatically inspect a project and build
|
|
|
279
279
|
- **Remove an obsolete skill** — delete a skill and its associated snippet, automatically cleaning up the index entry
|
|
280
280
|
- **Audit available skills** — list all published and draft skills with their descriptions to understand what automation is available for the project
|
|
281
281
|
|
|
282
|
+
##### Security Audits for skills.sh Skills
|
|
283
|
+
|
|
284
|
+
When discovering or installing skills from skills.sh, the plugin automatically checks security audit results from three independent providers:
|
|
285
|
+
|
|
286
|
+
- **Gen Agent Trust Hub** — AI-powered threat detection for malware, data exfiltration, and prompt injection
|
|
287
|
+
- **Socket** — Supply chain security analysis for suspicious patterns and anomalies
|
|
288
|
+
- **Snyk** — Vulnerability scanning and risk assessment
|
|
289
|
+
|
|
290
|
+
**Behavior:**
|
|
291
|
+
|
|
292
|
+
- **Block on Fail** — if any audit provider reports a failure, installation is blocked with details and a link to review the audit findings
|
|
293
|
+
- **Warn on Warn** — if any provider reports a warning, the skill is installed but warnings are displayed with links to the audit details
|
|
294
|
+
- **Graceful degradation** — if skills.sh is unreachable or audit data is unavailable, installation proceeds with a note
|
|
295
|
+
|
|
296
|
+
**Use cases:**
|
|
297
|
+
|
|
298
|
+
- **Discover skills with security status** — `gitlab_skill_discover` shows audit results (Pass/Warn/Fail) inline for each skills.sh result, so you can assess risk before installing
|
|
299
|
+
- **Block installation of risky skills** — skills with audit failures from any provider are automatically blocked with a link to the full audit report
|
|
300
|
+
- **Review audit warnings before proceeding** — skills with warnings install successfully but display the warnings so you can make an informed decision
|
|
301
|
+
- **Graceful handling of unavailable audit data** — if skills.sh is unreachable, install proceeds with a note rather than failing
|
|
302
|
+
|
|
282
303
|
### Dynamic Refresh
|
|
283
304
|
|
|
284
305
|
After enabling or disabling an agent/flow, the plugin automatically refreshes the
|
package/dist/index.cjs
CHANGED
|
@@ -4052,7 +4052,16 @@ function searchSkillsSh(query) {
|
|
|
4052
4052
|
function downloadSkillFromSkillsSh(identifier) {
|
|
4053
4053
|
const tmp = (0, import_fs2.mkdtempSync)((0, import_path2.join)((0, import_os2.tmpdir)(), "skill-install-"));
|
|
4054
4054
|
try {
|
|
4055
|
-
|
|
4055
|
+
const atIdx = identifier.indexOf("@");
|
|
4056
|
+
let cmd;
|
|
4057
|
+
if (atIdx !== -1) {
|
|
4058
|
+
const repo = identifier.slice(0, atIdx);
|
|
4059
|
+
const skill = identifier.slice(atIdx + 1);
|
|
4060
|
+
cmd = `npx skills add ${JSON.stringify(repo)} --skill ${JSON.stringify(skill)} -y --copy`;
|
|
4061
|
+
} else {
|
|
4062
|
+
cmd = `npx skills add ${JSON.stringify(identifier)} -y --copy`;
|
|
4063
|
+
}
|
|
4064
|
+
(0, import_child_process.execSync)(cmd, {
|
|
4056
4065
|
timeout: 6e4,
|
|
4057
4066
|
cwd: tmp,
|
|
4058
4067
|
encoding: "utf-8",
|
|
@@ -4105,6 +4114,73 @@ function downloadSkillFromSkillsSh(identifier) {
|
|
|
4105
4114
|
}
|
|
4106
4115
|
}
|
|
4107
4116
|
|
|
4117
|
+
// src/tools/skill-audit.ts
|
|
4118
|
+
var PROVIDER_NAMES = {
|
|
4119
|
+
"agent-trust-hub": "Gen Agent Trust Hub",
|
|
4120
|
+
socket: "Socket",
|
|
4121
|
+
snyk: "Snyk"
|
|
4122
|
+
};
|
|
4123
|
+
function parseIdentifierToUrl(identifier) {
|
|
4124
|
+
const atIdx = identifier.indexOf("@");
|
|
4125
|
+
if (atIdx === -1) return null;
|
|
4126
|
+
const ownerRepo = identifier.slice(0, atIdx);
|
|
4127
|
+
const skillName = identifier.slice(atIdx + 1);
|
|
4128
|
+
if (!ownerRepo.includes("/") || !skillName) return null;
|
|
4129
|
+
return `https://skills.sh/${ownerRepo}/${skillName}`;
|
|
4130
|
+
}
|
|
4131
|
+
function parseAuditHtml(html, auditUrl) {
|
|
4132
|
+
const secIdx = html.indexOf("Security Audits");
|
|
4133
|
+
if (secIdx === -1) return null;
|
|
4134
|
+
const section = html.slice(secIdx, secIdx + 5e3);
|
|
4135
|
+
const providerPattern = /href="[^"]*\/security\/(agent-trust-hub|socket|snyk)"[\s\S]*?>(Pass|Fail|Warn)</g;
|
|
4136
|
+
const results = [];
|
|
4137
|
+
let match;
|
|
4138
|
+
while ((match = providerPattern.exec(section)) !== null) {
|
|
4139
|
+
const slug = match[1];
|
|
4140
|
+
const status = match[2];
|
|
4141
|
+
results.push({
|
|
4142
|
+
provider: PROVIDER_NAMES[slug] ?? slug,
|
|
4143
|
+
status,
|
|
4144
|
+
detailUrl: `${auditUrl}/security/${slug}`
|
|
4145
|
+
});
|
|
4146
|
+
}
|
|
4147
|
+
if (results.length === 0) return null;
|
|
4148
|
+
return {
|
|
4149
|
+
results,
|
|
4150
|
+
hasFailure: results.some((r) => r.status === "Fail"),
|
|
4151
|
+
hasWarning: results.some((r) => r.status === "Warn"),
|
|
4152
|
+
auditUrl
|
|
4153
|
+
};
|
|
4154
|
+
}
|
|
4155
|
+
async function fetchSkillAudit(identifier) {
|
|
4156
|
+
const url = parseIdentifierToUrl(identifier);
|
|
4157
|
+
if (!url) return null;
|
|
4158
|
+
try {
|
|
4159
|
+
const resp = await fetch(url, {
|
|
4160
|
+
signal: AbortSignal.timeout(1e4),
|
|
4161
|
+
headers: { Accept: "text/html" }
|
|
4162
|
+
});
|
|
4163
|
+
if (!resp.ok) return null;
|
|
4164
|
+
const html = await resp.text();
|
|
4165
|
+
return parseAuditHtml(html, url);
|
|
4166
|
+
} catch {
|
|
4167
|
+
return null;
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
function formatAuditLine(audit) {
|
|
4171
|
+
return audit.results.map((r) => {
|
|
4172
|
+
const icon = r.status === "Fail" ? "\u{1F534}" : r.status === "Warn" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
4173
|
+
return `${icon} ${r.provider}: ${r.status}`;
|
|
4174
|
+
}).join(" | ");
|
|
4175
|
+
}
|
|
4176
|
+
function formatAuditRate(audit) {
|
|
4177
|
+
const total = audit.results.length;
|
|
4178
|
+
const passed = audit.results.filter((r) => r.status === "Pass").length;
|
|
4179
|
+
if (passed === total) return `Security: ${passed}/${total} audits passed \u2705`;
|
|
4180
|
+
if (audit.hasFailure) return `Security: ${passed}/${total} audits passed \u274C`;
|
|
4181
|
+
return `Security: ${passed}/${total} audits passed \u26A0\uFE0F`;
|
|
4182
|
+
}
|
|
4183
|
+
|
|
4108
4184
|
// src/tools/skill-tools.ts
|
|
4109
4185
|
var z6 = import_plugin6.tool.schema;
|
|
4110
4186
|
var PROJECT_ID_DESC2 = "Project path from git remote";
|
|
@@ -4389,14 +4465,32 @@ Install: \`gitlab_skill_install(name="${e.name}", source="group", group_id="${ar
|
|
|
4389
4465
|
}
|
|
4390
4466
|
const shResults = searchSkillsSh(args.query);
|
|
4391
4467
|
if (shResults.length > 0) {
|
|
4468
|
+
const audits = await Promise.all(shResults.map((r) => fetchSkillAudit(r.identifier)));
|
|
4392
4469
|
sections.push(
|
|
4393
4470
|
`### skills.sh (${shResults.length})
|
|
4394
4471
|
|
|
4395
|
-
` + shResults.map(
|
|
4396
|
-
|
|
4472
|
+
` + shResults.map((r, i) => {
|
|
4473
|
+
const audit = audits[i];
|
|
4474
|
+
let line = `**${r.identifier}** (${r.installs})`;
|
|
4475
|
+
if (audit) {
|
|
4476
|
+
line += `
|
|
4477
|
+
${formatAuditRate(audit)}`;
|
|
4478
|
+
line += `
|
|
4479
|
+
${formatAuditLine(audit)}`;
|
|
4480
|
+
if (audit.hasFailure) {
|
|
4481
|
+
line += `
|
|
4482
|
+
\u26D4 BLOCKED \u2014 security audit failures detected. Review: ${audit.auditUrl}`;
|
|
4483
|
+
return line;
|
|
4484
|
+
}
|
|
4485
|
+
} else {
|
|
4486
|
+
line += `
|
|
4487
|
+
Security: unknown (audit data unavailable)`;
|
|
4488
|
+
}
|
|
4489
|
+
line += `
|
|
4397
4490
|
${r.url}
|
|
4398
|
-
Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")
|
|
4399
|
-
|
|
4491
|
+
Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``;
|
|
4492
|
+
return line;
|
|
4493
|
+
}).join("\n\n")
|
|
4400
4494
|
);
|
|
4401
4495
|
}
|
|
4402
4496
|
if (sections.length === 0) {
|
|
@@ -4419,6 +4513,14 @@ Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``
|
|
|
4419
4513
|
const projectScope = resolveScope2(args);
|
|
4420
4514
|
const targetPrefix = args.draft ? DRAFTS_PREFIX : SKILLS_PREFIX;
|
|
4421
4515
|
if (args.source === "skills.sh") {
|
|
4516
|
+
const audit = await fetchSkillAudit(args.name);
|
|
4517
|
+
if (audit?.hasFailure) {
|
|
4518
|
+
const failures = audit.results.filter((r) => r.status === "Fail").map((r) => ` \u{1F534} ${r.provider}: Fail (${r.detailUrl})`).join("\n");
|
|
4519
|
+
return `\u26D4 Installation BLOCKED \u2014 security audit failure(s) detected:
|
|
4520
|
+
${failures}
|
|
4521
|
+
|
|
4522
|
+
Review the audit details before proceeding: ${audit.auditUrl}`;
|
|
4523
|
+
}
|
|
4422
4524
|
const downloaded = downloadSkillFromSkillsSh(args.name);
|
|
4423
4525
|
if (!downloaded) {
|
|
4424
4526
|
return `Failed to download skill "${args.name}" from skills.sh.`;
|
|
@@ -4470,7 +4572,19 @@ Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``
|
|
|
4470
4572
|
}
|
|
4471
4573
|
const parts = [`${wikiCount} wiki page(s)`];
|
|
4472
4574
|
if (hasBundle) parts.push(`${scriptFiles.length} bundled script(s)`);
|
|
4473
|
-
|
|
4575
|
+
let result = `Installed skill "${downloaded.name}" from skills.sh. ${parts.join(", ")}. Use gitlab_skill_setup to extract scripts.`;
|
|
4576
|
+
if (audit?.hasWarning) {
|
|
4577
|
+
const warnings = audit.results.filter((r) => r.status === "Warn").map((r) => ` \u26A0\uFE0F ${r.provider}: Warn (${r.detailUrl})`).join("\n");
|
|
4578
|
+
result += `
|
|
4579
|
+
|
|
4580
|
+
\u26A0\uFE0F Security audit warnings:
|
|
4581
|
+
${warnings}`;
|
|
4582
|
+
} else if (!audit) {
|
|
4583
|
+
result += `
|
|
4584
|
+
|
|
4585
|
+
(security audit data unavailable \u2014 skills.sh may be unreachable)`;
|
|
4586
|
+
}
|
|
4587
|
+
return result;
|
|
4474
4588
|
} catch (err) {
|
|
4475
4589
|
return `Error installing from skills.sh: ${err.message}`;
|
|
4476
4590
|
}
|