opencode-gitlab-dap 1.8.3 → 1.8.4

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 CHANGED
@@ -3612,13 +3612,13 @@ async function searchWikiPages(instanceUrl, token, scope, id, query) {
3612
3612
  // src/tools/memory-tools.ts
3613
3613
  var z5 = import_plugin5.tool.schema;
3614
3614
  var PREFIX = "agents";
3615
- var MEMORY_SLUGS = {
3615
+ var MEMORY_DIRS = {
3616
3616
  all: [`${PREFIX}/memory/facts`, `${PREFIX}/memory/decisions`, `${PREFIX}/memory/patterns`],
3617
3617
  facts: [`${PREFIX}/memory/facts`],
3618
3618
  decisions: [`${PREFIX}/memory/decisions`],
3619
3619
  patterns: [`${PREFIX}/memory/patterns`]
3620
3620
  };
3621
- var RECORD_SLUG = {
3621
+ var RECORD_DIR = {
3622
3622
  fact: `${PREFIX}/memory/facts`,
3623
3623
  decision: `${PREFIX}/memory/decisions`,
3624
3624
  pattern: `${PREFIX}/memory/patterns`
@@ -3629,52 +3629,9 @@ function today() {
3629
3629
  function slugify(text) {
3630
3630
  return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
3631
3631
  }
3632
- async function safeRead(instanceUrl, token, scope, id, slug) {
3633
- try {
3634
- const page = await getWikiPage(instanceUrl, token, scope, id, slug);
3635
- return page.content;
3636
- } catch {
3637
- return null;
3638
- }
3639
- }
3640
- var MAX_RETRIES = 3;
3641
- var RETRY_DELAY_MS = 1e3;
3642
- async function sleep2(ms) {
3643
- return new Promise((resolve) => setTimeout(resolve, ms));
3644
- }
3645
- async function appendToPage(instanceUrl, token, scope, id, slug, newContent) {
3646
- for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
3647
- const existing2 = await safeRead(instanceUrl, token, scope, id, slug);
3648
- if (existing2 !== null) {
3649
- try {
3650
- await updateWikiPage(instanceUrl, token, scope, id, slug, existing2 + "\n\n" + newContent);
3651
- return;
3652
- } catch (err) {
3653
- if (attempt < MAX_RETRIES - 1 && err.message?.includes("reference update")) {
3654
- await sleep2(RETRY_DELAY_MS * (attempt + 1));
3655
- continue;
3656
- }
3657
- throw err;
3658
- }
3659
- } else {
3660
- try {
3661
- await createWikiPage(instanceUrl, token, scope, id, slug, newContent);
3662
- return;
3663
- } catch (err) {
3664
- if (err.message?.includes("Duplicate page") || err.message?.includes("reference update")) {
3665
- await sleep2(RETRY_DELAY_MS * (attempt + 1));
3666
- continue;
3667
- }
3668
- throw err;
3669
- }
3670
- }
3671
- }
3672
- const existing = await safeRead(instanceUrl, token, scope, id, slug);
3673
- if (existing !== null) {
3674
- await updateWikiPage(instanceUrl, token, scope, id, slug, existing + "\n\n" + newContent);
3675
- } else {
3676
- throw new Error(`Failed to append to ${slug} after ${MAX_RETRIES} retries`);
3677
- }
3632
+ function titleFromContent(content) {
3633
+ const first = content.split("\n")[0].replace(/^[#*\->\s]+/, "").trim();
3634
+ return first.slice(0, 80) || "untitled";
3678
3635
  }
3679
3636
  function validateProjectId(projectId) {
3680
3637
  if (!projectId.includes("/")) {
@@ -3711,25 +3668,38 @@ function makeMemoryTools(ctx) {
3711
3668
  const auth = authAndValidate(args.project_id);
3712
3669
  const { scope, id } = resolveScope(args);
3713
3670
  const memType = args.type ?? "all";
3714
- const slugs = MEMORY_SLUGS[memType];
3715
- if (!slugs) return `Unknown memory type: ${memType}`;
3716
- const sections = [];
3717
- for (const slug of slugs) {
3718
- const content = await safeRead(auth.instanceUrl, auth.token, scope, id, slug);
3719
- if (content) {
3720
- const label = slug.split("/").pop();
3721
- sections.push(`## ${label.charAt(0).toUpperCase() + label.slice(1)}
3671
+ const dirs = MEMORY_DIRS[memType];
3672
+ if (!dirs) return `Unknown memory type: ${memType}`;
3673
+ try {
3674
+ const allPages = await listWikiPages(
3675
+ auth.instanceUrl,
3676
+ auth.token,
3677
+ scope,
3678
+ id,
3679
+ true
3680
+ );
3681
+ const sections = [];
3682
+ for (const dir of dirs) {
3683
+ const label = dir.split("/").pop();
3684
+ const pages = allPages.filter((p) => p.slug.startsWith(dir + "/") && p.content);
3685
+ if (pages.length === 0) continue;
3686
+ const entries = pages.map((p) => p.content).join("\n\n---\n\n");
3687
+ sections.push(
3688
+ `## ${label.charAt(0).toUpperCase() + label.slice(1)} (${pages.length})
3722
3689
 
3723
- ${content}`);
3690
+ ${entries}`
3691
+ );
3724
3692
  }
3693
+ if (sections.length === 0)
3694
+ return "No project memory found. Use gitlab_memory_record to start building project knowledge.";
3695
+ return sections.join("\n\n---\n\n");
3696
+ } catch (err) {
3697
+ return `Error loading memory: ${err.message}`;
3725
3698
  }
3726
- if (sections.length === 0)
3727
- return "No project memory found. Use gitlab_memory_record to start building project knowledge.";
3728
- return sections.join("\n\n---\n\n");
3729
3699
  }
3730
3700
  }),
3731
3701
  gitlab_memory_record: (0, import_plugin5.tool)({
3732
- description: "Record a fact, decision, or pattern in project memory.\nFacts: stable truths about the project (e.g., deploy targets, tech stack, team conventions).\nDecisions: architectural choices with reasoning (why X was chosen over Y).\nPatterns: recurring observations that may evolve into skills over time.\nEntries are automatically timestamped and appended to the appropriate memory page.\nMultiple facts can be recorded in a single call by separating them with newlines.",
3702
+ description: "Record a fact, decision, or pattern in project memory.\nFacts: stable truths about the project (e.g., deploy targets, tech stack, team conventions).\nDecisions: architectural choices with reasoning (why X was chosen over Y).\nPatterns: recurring observations that may evolve into skills over time.\nEach record creates its own page \u2014 safe for parallel writes.",
3733
3703
  args: {
3734
3704
  project_id: z5.string().describe(
3735
3705
  'FULL project path with namespace (e.g., "gitlab-org/gitlab"). Must contain a slash. Never use just the project name.'
@@ -3742,24 +3712,18 @@ ${content}`);
3742
3712
  execute: async (args) => {
3743
3713
  const auth = authAndValidate(args.project_id);
3744
3714
  const { scope, id } = resolveScope(args);
3745
- const slug = RECORD_SLUG[args.type];
3746
- if (!slug) return `Unknown memory type: ${args.type}`;
3715
+ const dir = RECORD_DIR[args.type];
3716
+ if (!dir) return `Unknown memory type: ${args.type}`;
3747
3717
  const date = today();
3748
- let formatted;
3749
- if (args.type === "decision") {
3750
- const firstLine = args.content.split("\n")[0];
3751
- const rest = args.content.split("\n").slice(1).join("\n").trim();
3752
- formatted = `## ${date}: ${firstLine}${rest ? "\n" + rest : ""}`;
3753
- } else if (args.type === "fact") {
3754
- formatted = `## ${date}
3755
- - ${args.content.replace(/\n/g, "\n- ")}`;
3756
- } else {
3757
- formatted = `## ${date}
3758
- ${args.content}`;
3759
- }
3718
+ const title = titleFromContent(args.content);
3719
+ const slug = `${dir}/${date}-${slugify(title)}`;
3720
+ const header = `*Recorded: ${date} | Type: ${args.type}*
3721
+
3722
+ `;
3723
+ const body = header + args.content;
3760
3724
  try {
3761
- await appendToPage(auth.instanceUrl, auth.token, scope, id, slug, formatted);
3762
- return `Recorded ${args.type} in project memory.`;
3725
+ await createWikiPage(auth.instanceUrl, auth.token, scope, id, slug, body);
3726
+ return `Recorded ${args.type} in project memory: ${slug}`;
3763
3727
  } catch (err) {
3764
3728
  return `Error recording ${args.type}: ${err.message}`;
3765
3729
  }
@@ -3815,32 +3779,12 @@ ${args.content}`;
3815
3779
  const { scope, id } = resolveScope(args);
3816
3780
  const date = today();
3817
3781
  const slug = `${PREFIX}/memory/sessions/${date}-${slugify(args.title)}`;
3818
- for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
3819
- try {
3820
- await createWikiPage(auth.instanceUrl, auth.token, scope, id, slug, args.summary);
3821
- return `Session logged: ${slug}`;
3822
- } catch (err) {
3823
- const msg = err.message ?? "";
3824
- if (msg.includes("Duplicate page") || msg.includes("already exists") || msg.includes("422")) {
3825
- try {
3826
- await updateWikiPage(auth.instanceUrl, auth.token, scope, id, slug, args.summary);
3827
- return `Session log updated: ${slug}`;
3828
- } catch (err2) {
3829
- if (attempt < MAX_RETRIES - 1 && err2.message?.includes("reference update")) {
3830
- await sleep2(RETRY_DELAY_MS * (attempt + 1));
3831
- continue;
3832
- }
3833
- return `Error logging session: ${err2.message}`;
3834
- }
3835
- }
3836
- if (attempt < MAX_RETRIES - 1 && msg.includes("reference update")) {
3837
- await sleep2(RETRY_DELAY_MS * (attempt + 1));
3838
- continue;
3839
- }
3840
- return `Error logging session: ${msg}`;
3841
- }
3782
+ try {
3783
+ await createWikiPage(auth.instanceUrl, auth.token, scope, id, slug, args.summary);
3784
+ return `Session logged: ${slug}`;
3785
+ } catch (err) {
3786
+ return `Error logging session: ${err.message}`;
3842
3787
  }
3843
- return `Error logging session: failed after ${MAX_RETRIES} retries`;
3844
3788
  }
3845
3789
  })
3846
3790
  };