opencode-gitlab-dap 1.16.4 → 1.16.5
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/index.cjs +33 -124
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +33 -124
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3781,73 +3781,6 @@ ${e.content}`).join("\n\n---\n\n");
|
|
|
3781
3781
|
|
|
3782
3782
|
// src/tools/skill-tools.ts
|
|
3783
3783
|
import { tool as tool6 } from "@opencode-ai/plugin";
|
|
3784
|
-
|
|
3785
|
-
// src/snippets.ts
|
|
3786
|
-
function snippetApi(instanceUrl, token, projectId) {
|
|
3787
|
-
const base = instanceUrl.replace(/\/$/, "");
|
|
3788
|
-
const encoded = typeof projectId === "number" ? projectId : encodeURIComponent(projectId);
|
|
3789
|
-
return {
|
|
3790
|
-
url: `${base}/api/v4/projects/${encoded}/snippets`,
|
|
3791
|
-
headers: {
|
|
3792
|
-
"Content-Type": "application/json",
|
|
3793
|
-
Authorization: `Bearer ${token}`
|
|
3794
|
-
}
|
|
3795
|
-
};
|
|
3796
|
-
}
|
|
3797
|
-
async function handleResponse2(res) {
|
|
3798
|
-
if (!res.ok) {
|
|
3799
|
-
const text = await res.text();
|
|
3800
|
-
throw new Error(`Snippet API error (${res.status}): ${text}`);
|
|
3801
|
-
}
|
|
3802
|
-
return res.json();
|
|
3803
|
-
}
|
|
3804
|
-
async function createProjectSnippet(instanceUrl, token, projectId, title, description, files, visibility = "private") {
|
|
3805
|
-
const { url, headers } = snippetApi(instanceUrl, token, projectId);
|
|
3806
|
-
const res = await fetch(url, {
|
|
3807
|
-
method: "POST",
|
|
3808
|
-
headers,
|
|
3809
|
-
body: JSON.stringify({ title, description, visibility, files })
|
|
3810
|
-
});
|
|
3811
|
-
return handleResponse2(res);
|
|
3812
|
-
}
|
|
3813
|
-
async function deleteProjectSnippet(instanceUrl, token, projectId, snippetId) {
|
|
3814
|
-
const { url, headers } = snippetApi(instanceUrl, token, projectId);
|
|
3815
|
-
const res = await fetch(`${url}/${snippetId}`, { method: "DELETE", headers });
|
|
3816
|
-
if (!res.ok) {
|
|
3817
|
-
const text = await res.text();
|
|
3818
|
-
throw new Error(`Snippet API error (${res.status}): ${text}`);
|
|
3819
|
-
}
|
|
3820
|
-
}
|
|
3821
|
-
async function getSnippetFileRaw(instanceUrl, token, projectId, snippetId, filePath, ref = "main") {
|
|
3822
|
-
const base = instanceUrl.replace(/\/$/, "");
|
|
3823
|
-
const encoded = typeof projectId === "number" ? projectId : encodeURIComponent(projectId);
|
|
3824
|
-
const encodedPath = encodeURIComponent(filePath);
|
|
3825
|
-
const url = `${base}/api/v4/projects/${encoded}/snippets/${snippetId}/files/${ref}/${encodedPath}/raw`;
|
|
3826
|
-
const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
|
|
3827
|
-
if (!res.ok) {
|
|
3828
|
-
const text = await res.text();
|
|
3829
|
-
throw new Error(`Snippet file API error (${res.status}): ${text}`);
|
|
3830
|
-
}
|
|
3831
|
-
return res.text();
|
|
3832
|
-
}
|
|
3833
|
-
async function listSnippetFiles(instanceUrl, token, projectId, snippetId) {
|
|
3834
|
-
const base = instanceUrl.replace(/\/$/, "");
|
|
3835
|
-
const encoded = typeof projectId === "number" ? projectId : encodeURIComponent(projectId);
|
|
3836
|
-
const url = `${base}/api/v4/projects/${encoded}/snippets/${snippetId}`;
|
|
3837
|
-
const res = await fetch(url, {
|
|
3838
|
-
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }
|
|
3839
|
-
});
|
|
3840
|
-
const snippet = await handleResponse2(res);
|
|
3841
|
-
if (snippet.files) {
|
|
3842
|
-
return snippet.files.map((f) => ({ path: f.path, raw_url: f.raw_url }));
|
|
3843
|
-
}
|
|
3844
|
-
if (snippet.file_name) {
|
|
3845
|
-
return [{ path: snippet.file_name, raw_url: snippet.raw_url }];
|
|
3846
|
-
}
|
|
3847
|
-
return [];
|
|
3848
|
-
}
|
|
3849
|
-
|
|
3850
|
-
// src/tools/skill-tools.ts
|
|
3851
3784
|
import { writeFileSync as writeFileSync2, mkdirSync, chmodSync } from "fs";
|
|
3852
3785
|
import { join as join3, dirname } from "path";
|
|
3853
3786
|
|
|
@@ -3881,14 +3814,12 @@ function parseFrontmatter(content) {
|
|
|
3881
3814
|
if (k === "name") meta.name = val;
|
|
3882
3815
|
else if (k === "description") meta.description = val;
|
|
3883
3816
|
else if (k === "source") meta.source = val;
|
|
3884
|
-
else if (k === "snippet") meta.snippetId = parseInt(val, 10) || void 0;
|
|
3885
3817
|
}
|
|
3886
3818
|
return { meta, body: match[2] };
|
|
3887
3819
|
}
|
|
3888
3820
|
function formatFrontmatter(meta, body) {
|
|
3889
3821
|
const lines = ["---", `name: ${meta.name}`, `description: ${meta.description}`];
|
|
3890
3822
|
if (meta.source) lines.push(`source: ${meta.source}`);
|
|
3891
|
-
if (meta.snippetId) lines.push(`snippet: ${meta.snippetId}`);
|
|
3892
3823
|
lines.push("---", "");
|
|
3893
3824
|
return lines.join("\n") + body;
|
|
3894
3825
|
}
|
|
@@ -4046,11 +3977,12 @@ async function listSkills(instanceUrl, token, scope, id, prefix) {
|
|
|
4046
3977
|
const name = extractSkillNameFromSlug(page.slug, prefix);
|
|
4047
3978
|
if (!name || !page.content) continue;
|
|
4048
3979
|
const { meta } = parseFrontmatter(page.content);
|
|
3980
|
+
const hasBundle = pages.some((p) => p.slug === `${prefix}/${name}/bundle`);
|
|
4049
3981
|
skills.push({
|
|
4050
3982
|
name: meta.name ?? name,
|
|
4051
3983
|
description: meta.description ?? "",
|
|
4052
3984
|
source: meta.source,
|
|
4053
|
-
|
|
3985
|
+
hasScripts: hasBundle,
|
|
4054
3986
|
draft: prefix === DRAFTS_PREFIX
|
|
4055
3987
|
});
|
|
4056
3988
|
}
|
|
@@ -4116,7 +4048,7 @@ function makeSkillTools(ctx) {
|
|
|
4116
4048
|
id,
|
|
4117
4049
|
`${prefix}/${args.name}/SKILL`
|
|
4118
4050
|
);
|
|
4119
|
-
const {
|
|
4051
|
+
const { body } = parseFrontmatter(page.content);
|
|
4120
4052
|
const isDraft = prefix === DRAFTS_PREFIX;
|
|
4121
4053
|
const pages = await listWikiPages(auth.instanceUrl, auth.token, scope, id);
|
|
4122
4054
|
const skillPrefix = `${prefix}/${args.name}/`;
|
|
@@ -4132,10 +4064,11 @@ ${body}` : body;
|
|
|
4132
4064
|
---
|
|
4133
4065
|
Available references: ${refs.join(", ")}`;
|
|
4134
4066
|
}
|
|
4135
|
-
|
|
4067
|
+
const hasBundle = refs.some((r) => r === "bundle");
|
|
4068
|
+
if (hasBundle) {
|
|
4136
4069
|
result += `
|
|
4137
4070
|
|
|
4138
|
-
This skill has executable scripts
|
|
4071
|
+
This skill has executable scripts.`;
|
|
4139
4072
|
result += `
|
|
4140
4073
|
Run \`gitlab_skill_setup(name="${args.name}")\` to extract them locally.`;
|
|
4141
4074
|
}
|
|
@@ -4332,25 +4265,12 @@ Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``
|
|
|
4332
4265
|
try {
|
|
4333
4266
|
const mdFiles = downloaded.files.filter((f) => isMarkdownFile(f.path));
|
|
4334
4267
|
const scriptFiles = downloaded.files.filter((f) => !isMarkdownFile(f.path));
|
|
4335
|
-
|
|
4336
|
-
if (scriptFiles.length > 0) {
|
|
4337
|
-
const snippet = await createProjectSnippet(
|
|
4338
|
-
auth.instanceUrl,
|
|
4339
|
-
auth.token,
|
|
4340
|
-
args.project_id,
|
|
4341
|
-
`skill:${downloaded.name}`,
|
|
4342
|
-
`Scripts for skill "${downloaded.name}"`,
|
|
4343
|
-
[{ file_path: `${downloaded.name}.bundle`, content: packFiles(scriptFiles) }],
|
|
4344
|
-
"private"
|
|
4345
|
-
);
|
|
4346
|
-
snippetId = snippet.id;
|
|
4347
|
-
}
|
|
4268
|
+
const hasBundle = scriptFiles.length > 0;
|
|
4348
4269
|
const skillBody = formatFrontmatter(
|
|
4349
4270
|
{
|
|
4350
4271
|
name: downloaded.name,
|
|
4351
4272
|
description: downloaded.description,
|
|
4352
|
-
source: `skills.sh:${args.name}
|
|
4353
|
-
snippetId
|
|
4273
|
+
source: `skills.sh:${args.name}`
|
|
4354
4274
|
},
|
|
4355
4275
|
downloaded.content.replace(/^---[\s\S]*?---\s*\n/, "")
|
|
4356
4276
|
);
|
|
@@ -4375,8 +4295,20 @@ Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``
|
|
|
4375
4295
|
);
|
|
4376
4296
|
wikiCount++;
|
|
4377
4297
|
}
|
|
4298
|
+
if (hasBundle) {
|
|
4299
|
+
const bundleSlug = `${targetPrefix}/${downloaded.name}/bundle`;
|
|
4300
|
+
await upsertPage(
|
|
4301
|
+
auth.instanceUrl,
|
|
4302
|
+
auth.token,
|
|
4303
|
+
projectScope.scope,
|
|
4304
|
+
projectScope.id,
|
|
4305
|
+
bundleSlug,
|
|
4306
|
+
packFiles(scriptFiles)
|
|
4307
|
+
);
|
|
4308
|
+
wikiCount++;
|
|
4309
|
+
}
|
|
4378
4310
|
const parts = [`${wikiCount} wiki page(s)`];
|
|
4379
|
-
if (
|
|
4311
|
+
if (hasBundle) parts.push(`${scriptFiles.length} bundled script(s)`);
|
|
4380
4312
|
return `Installed skill "${downloaded.name}" from skills.sh. ${parts.join(", ")}. Use gitlab_skill_setup to extract scripts.`;
|
|
4381
4313
|
} catch (err) {
|
|
4382
4314
|
return `Error installing from skills.sh: ${err.message}`;
|
|
@@ -4444,7 +4376,7 @@ Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``
|
|
|
4444
4376
|
if (!skillPage) {
|
|
4445
4377
|
return `Skill "${args.name}" not found. Use gitlab_skill_list to see available skills.`;
|
|
4446
4378
|
}
|
|
4447
|
-
const {
|
|
4379
|
+
const { body } = parseFrontmatter(skillPage.content);
|
|
4448
4380
|
mkdirSync(targetDir, { recursive: true });
|
|
4449
4381
|
writeFileSync2(join3(targetDir, "SKILL.md"), body);
|
|
4450
4382
|
const pages = await listWikiPages(
|
|
@@ -4469,23 +4401,17 @@ Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``
|
|
|
4469
4401
|
}
|
|
4470
4402
|
}
|
|
4471
4403
|
let scriptCount = 0;
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
auth.token,
|
|
4476
|
-
args.project_id,
|
|
4477
|
-
meta.snippetId
|
|
4478
|
-
);
|
|
4479
|
-
for (const bf of bundleFiles) {
|
|
4480
|
-
const raw = await getSnippetFileRaw(
|
|
4404
|
+
for (const prefix of [SKILLS_PREFIX, DRAFTS_PREFIX]) {
|
|
4405
|
+
try {
|
|
4406
|
+
const bundlePage = await getWikiPage(
|
|
4481
4407
|
auth.instanceUrl,
|
|
4482
4408
|
auth.token,
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4409
|
+
scope,
|
|
4410
|
+
id,
|
|
4411
|
+
`${prefix}/${args.name}/bundle`
|
|
4486
4412
|
);
|
|
4487
|
-
if (
|
|
4488
|
-
for (const file of unpackFiles(
|
|
4413
|
+
if (bundlePage.content) {
|
|
4414
|
+
for (const file of unpackFiles(bundlePage.content)) {
|
|
4489
4415
|
const filePath = join3(targetDir, file.path);
|
|
4490
4416
|
mkdirSync(dirname(filePath), { recursive: true });
|
|
4491
4417
|
writeFileSync2(filePath, file.content);
|
|
@@ -4493,6 +4419,8 @@ Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``
|
|
|
4493
4419
|
scriptCount++;
|
|
4494
4420
|
}
|
|
4495
4421
|
}
|
|
4422
|
+
break;
|
|
4423
|
+
} catch {
|
|
4496
4424
|
}
|
|
4497
4425
|
}
|
|
4498
4426
|
ensureGitignore(workDir);
|
|
@@ -4525,29 +4453,10 @@ Install: \`gitlab_skill_install(name="${r.identifier}", source="skills.sh")\``
|
|
|
4525
4453
|
if (skillPages.length === 0) {
|
|
4526
4454
|
return `Skill "${args.name}" not found.`;
|
|
4527
4455
|
}
|
|
4528
|
-
const skillPage = await getWikiPage(
|
|
4529
|
-
auth.instanceUrl,
|
|
4530
|
-
auth.token,
|
|
4531
|
-
scope,
|
|
4532
|
-
id,
|
|
4533
|
-
`${prefix}/${args.name}/SKILL`
|
|
4534
|
-
);
|
|
4535
|
-
const { meta } = parseFrontmatter(skillPage.content);
|
|
4536
4456
|
for (const page of skillPages) {
|
|
4537
4457
|
await deleteWikiPage(auth.instanceUrl, auth.token, scope, id, page.slug);
|
|
4538
4458
|
}
|
|
4539
|
-
|
|
4540
|
-
try {
|
|
4541
|
-
await deleteProjectSnippet(
|
|
4542
|
-
auth.instanceUrl,
|
|
4543
|
-
auth.token,
|
|
4544
|
-
args.project_id,
|
|
4545
|
-
meta.snippetId
|
|
4546
|
-
);
|
|
4547
|
-
} catch {
|
|
4548
|
-
}
|
|
4549
|
-
}
|
|
4550
|
-
return `Deleted skill "${args.name}" (${skillPages.length} page(s)${meta.snippetId ? " + snippet" : ""}).`;
|
|
4459
|
+
return `Deleted skill "${args.name}" (${skillPages.length} page(s) removed).`;
|
|
4551
4460
|
} catch (err) {
|
|
4552
4461
|
return `Error deleting skill: ${err.message}`;
|
|
4553
4462
|
}
|