opencode-gitlab-dap 1.8.1 → 1.8.2

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
@@ -3645,6 +3645,12 @@ async function appendToPage(instanceUrl, token, scope, id, slug, newContent) {
3645
3645
  await createWikiPage(instanceUrl, token, scope, id, slug, newContent);
3646
3646
  }
3647
3647
  }
3648
+ function validateProjectId(projectId) {
3649
+ if (!projectId.includes("/")) {
3650
+ return `Invalid project_id "${projectId}". Must be the full project path containing at least one slash (e.g., "my-group/my-project"), not just the project name.`;
3651
+ }
3652
+ return null;
3653
+ }
3648
3654
  function resolveScope(args) {
3649
3655
  if (args.scope === "groups" && args.group_id) {
3650
3656
  return { scope: "groups", id: args.group_id };
@@ -3652,18 +3658,26 @@ function resolveScope(args) {
3652
3658
  return { scope: "projects", id: args.project_id };
3653
3659
  }
3654
3660
  function makeMemoryTools(ctx) {
3661
+ function authAndValidate(projectId) {
3662
+ const auth = ctx.ensureAuth();
3663
+ if (!auth) throw new Error("GitLab authentication not available");
3664
+ const err = validateProjectId(projectId);
3665
+ if (err) throw new Error(err);
3666
+ return auth;
3667
+ }
3655
3668
  return {
3656
3669
  gitlab_memory_load: (0, import_plugin5.tool)({
3657
3670
  description: "Load project memory to understand context, known facts, past decisions, and observed patterns.\nUse this at the start of complex tasks to check what is already known about the project.\nReturns accumulated knowledge from previous sessions.",
3658
3671
  args: {
3659
- project_id: z5.string().describe('Project path (e.g., "gitlab-org/gitlab"). Use the same value consistently.'),
3672
+ project_id: z5.string().describe(
3673
+ 'FULL project path with namespace (e.g., "gitlab-org/gitlab"). Must contain a slash. Never use just the project name.'
3674
+ ),
3660
3675
  type: z5.enum(["all", "facts", "decisions", "patterns"]).optional().describe('Which memory to load: "all" (default), "facts", "decisions", or "patterns"'),
3661
3676
  scope: z5.enum(["projects", "groups"]).optional().describe("Scope (default: projects)"),
3662
3677
  group_id: z5.string().optional().describe("Group path (required when scope is groups)")
3663
3678
  },
3664
3679
  execute: async (args) => {
3665
- const auth = ctx.ensureAuth();
3666
- if (!auth) throw new Error("GitLab authentication not available");
3680
+ const auth = authAndValidate(args.project_id);
3667
3681
  const { scope, id } = resolveScope(args);
3668
3682
  const memType = args.type ?? "all";
3669
3683
  const slugs = MEMORY_SLUGS[memType];
@@ -3686,15 +3700,16 @@ ${content}`);
3686
3700
  gitlab_memory_record: (0, import_plugin5.tool)({
3687
3701
  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.",
3688
3702
  args: {
3689
- project_id: z5.string().describe('Project path (e.g., "gitlab-org/gitlab"). Use the same value consistently.'),
3703
+ project_id: z5.string().describe(
3704
+ 'FULL project path with namespace (e.g., "gitlab-org/gitlab"). Must contain a slash. Never use just the project name.'
3705
+ ),
3690
3706
  type: z5.enum(["fact", "decision", "pattern"]).describe("Type of knowledge to record"),
3691
3707
  content: z5.string().describe("The knowledge to record (markdown)"),
3692
3708
  scope: z5.enum(["projects", "groups"]).optional().describe("Scope (default: projects)"),
3693
3709
  group_id: z5.string().optional().describe("Group path (required when scope is groups)")
3694
3710
  },
3695
3711
  execute: async (args) => {
3696
- const auth = ctx.ensureAuth();
3697
- if (!auth) throw new Error("GitLab authentication not available");
3712
+ const auth = authAndValidate(args.project_id);
3698
3713
  const { scope, id } = resolveScope(args);
3699
3714
  const slug = RECORD_SLUG[args.type];
3700
3715
  if (!slug) return `Unknown memory type: ${args.type}`;
@@ -3722,14 +3737,15 @@ ${args.content}`;
3722
3737
  gitlab_memory_recall: (0, import_plugin5.tool)({
3723
3738
  description: "Search project knowledge for relevant information.\nSearches across all memory pages, session logs, and skills.\nUse this to check if something is already known before investigating.",
3724
3739
  args: {
3725
- project_id: z5.string().describe('Project path (e.g., "gitlab-org/gitlab"). Use the same value consistently.'),
3740
+ project_id: z5.string().describe(
3741
+ 'FULL project path with namespace (e.g., "gitlab-org/gitlab"). Must contain a slash. Never use just the project name.'
3742
+ ),
3726
3743
  query: z5.string().describe("What to search for"),
3727
3744
  scope: z5.enum(["projects", "groups"]).optional().describe("Scope (default: projects)"),
3728
3745
  group_id: z5.string().optional().describe("Group path (required when scope is groups)")
3729
3746
  },
3730
3747
  execute: async (args) => {
3731
- const auth = ctx.ensureAuth();
3732
- if (!auth) throw new Error("GitLab authentication not available");
3748
+ const auth = authAndValidate(args.project_id);
3733
3749
  const { scope, id } = resolveScope(args);
3734
3750
  try {
3735
3751
  const results = await searchWikiPages(
@@ -3753,7 +3769,9 @@ ${args.content}`;
3753
3769
  gitlab_memory_log_session: (0, import_plugin5.tool)({
3754
3770
  description: "Log a session summary including what was accomplished, what was learned, and any suggestions.\nUse this at the end of significant work sessions to preserve context for future sessions.",
3755
3771
  args: {
3756
- project_id: z5.string().describe('Project path (e.g., "gitlab-org/gitlab"). Use the same value consistently.'),
3772
+ project_id: z5.string().describe(
3773
+ 'FULL project path with namespace (e.g., "gitlab-org/gitlab"). Must contain a slash. Never use just the project name.'
3774
+ ),
3757
3775
  title: z5.string().describe('Brief session title (e.g., "fix-ai-gateway-healthcheck")'),
3758
3776
  summary: z5.string().describe(
3759
3777
  "Session summary in markdown (what happened, what was learned, what went wrong)"
@@ -3762,8 +3780,7 @@ ${args.content}`;
3762
3780
  group_id: z5.string().optional().describe("Group path (required when scope is groups)")
3763
3781
  },
3764
3782
  execute: async (args) => {
3765
- const auth = ctx.ensureAuth();
3766
- if (!auth) throw new Error("GitLab authentication not available");
3783
+ const auth = authAndValidate(args.project_id);
3767
3784
  const { scope, id } = resolveScope(args);
3768
3785
  const date = today();
3769
3786
  const slug = `${PREFIX}/memory/sessions/${date}-${slugify(args.title)}`;
@@ -3798,19 +3815,33 @@ function resolveScope2(args) {
3798
3815
  }
3799
3816
  return { scope: "projects", id: args.project_id };
3800
3817
  }
3818
+ function validateProjectId2(projectId) {
3819
+ if (!projectId.includes("/")) {
3820
+ return `Invalid project_id "${projectId}". Must be the full project path containing at least one slash (e.g., "my-group/my-project"), not just the project name.`;
3821
+ }
3822
+ return null;
3823
+ }
3801
3824
  function makeSkillTools(ctx) {
3825
+ function authAndValidate(projectId) {
3826
+ const auth = ctx.ensureAuth();
3827
+ if (!auth) throw new Error("GitLab authentication not available");
3828
+ const err = validateProjectId2(projectId);
3829
+ if (err) throw new Error(err);
3830
+ return auth;
3831
+ }
3802
3832
  return {
3803
3833
  gitlab_skill_list: (0, import_plugin6.tool)({
3804
3834
  description: "List available project skills and optionally draft skills.\nSkills define step-by-step procedures for common tasks (e.g., incident retros, debugging, deployments).",
3805
3835
  args: {
3806
- project_id: z6.string().describe('Project path (e.g., "gitlab-org/gitlab"). Use the same value consistently.'),
3836
+ project_id: z6.string().describe(
3837
+ 'FULL project path with namespace (e.g., "gitlab-org/gitlab"). Must contain a slash. Never use just the project name.'
3838
+ ),
3807
3839
  include_drafts: z6.boolean().optional().describe("Also list draft skills (default: false)"),
3808
3840
  scope: z6.enum(["projects", "groups"]).optional().describe("Scope (default: projects)"),
3809
3841
  group_id: z6.string().optional().describe("Group path (required when scope is groups)")
3810
3842
  },
3811
3843
  execute: async (args) => {
3812
- const auth = ctx.ensureAuth();
3813
- if (!auth) throw new Error("GitLab authentication not available");
3844
+ const auth = authAndValidate(args.project_id);
3814
3845
  const { scope, id } = resolveScope2(args);
3815
3846
  try {
3816
3847
  const pages = await listWikiPages(auth.instanceUrl, auth.token, scope, id);
@@ -3840,14 +3871,15 @@ function makeSkillTools(ctx) {
3840
3871
  gitlab_skill_load: (0, import_plugin6.tool)({
3841
3872
  description: "Load a specific skill by name.\nSkills contain step-by-step instructions for common tasks.\nChecks published skills first, then falls back to draft skills.",
3842
3873
  args: {
3843
- project_id: z6.string().describe('Project path (e.g., "gitlab-org/gitlab"). Use the same value consistently.'),
3874
+ project_id: z6.string().describe(
3875
+ 'FULL project path with namespace (e.g., "gitlab-org/gitlab"). Must contain a slash. Never use just the project name.'
3876
+ ),
3844
3877
  name: z6.string().describe('Skill name (e.g., "incident-retro", "helm-rollback")'),
3845
3878
  scope: z6.enum(["projects", "groups"]).optional().describe("Scope (default: projects)"),
3846
3879
  group_id: z6.string().optional().describe("Group path (required when scope is groups)")
3847
3880
  },
3848
3881
  execute: async (args) => {
3849
- const auth = ctx.ensureAuth();
3850
- if (!auth) throw new Error("GitLab authentication not available");
3882
+ const auth = authAndValidate(args.project_id);
3851
3883
  const { scope, id } = resolveScope2(args);
3852
3884
  try {
3853
3885
  const page = await getWikiPage(
@@ -3879,7 +3911,9 @@ ${draft.content}`;
3879
3911
  gitlab_skill_save: (0, import_plugin6.tool)({
3880
3912
  description: "Create or update a skill.\nSkills define step-by-step procedures for common tasks.\nUse draft=true for skills that haven't been proven yet.",
3881
3913
  args: {
3882
- project_id: z6.string().describe('Project path (e.g., "gitlab-org/gitlab"). Use the same value consistently.'),
3914
+ project_id: z6.string().describe(
3915
+ 'FULL project path with namespace (e.g., "gitlab-org/gitlab"). Must contain a slash. Never use just the project name.'
3916
+ ),
3883
3917
  name: z6.string().describe('Skill name (e.g., "incident-retro")'),
3884
3918
  content: z6.string().describe("Skill content in markdown"),
3885
3919
  draft: z6.boolean().optional().describe("Save as draft skill (default: false)"),
@@ -3887,8 +3921,7 @@ ${draft.content}`;
3887
3921
  group_id: z6.string().optional().describe("Group path (required when scope is groups)")
3888
3922
  },
3889
3923
  execute: async (args) => {
3890
- const auth = ctx.ensureAuth();
3891
- if (!auth) throw new Error("GitLab authentication not available");
3924
+ const auth = authAndValidate(args.project_id);
3892
3925
  const { scope, id } = resolveScope2(args);
3893
3926
  const prefix = args.draft ? DRAFTS_PREFIX : SKILLS_PREFIX;
3894
3927
  const slug = `${prefix}/${args.name}`;
@@ -3908,14 +3941,15 @@ ${draft.content}`;
3908
3941
  gitlab_skill_promote: (0, import_plugin6.tool)({
3909
3942
  description: "Promote a draft skill to published.\nMoves the skill from the drafts directory to the published skills directory.",
3910
3943
  args: {
3911
- project_id: z6.string().describe('Project path (e.g., "gitlab-org/gitlab"). Use the same value consistently.'),
3944
+ project_id: z6.string().describe(
3945
+ 'FULL project path with namespace (e.g., "gitlab-org/gitlab"). Must contain a slash. Never use just the project name.'
3946
+ ),
3912
3947
  name: z6.string().describe("Skill name to promote"),
3913
3948
  scope: z6.enum(["projects", "groups"]).optional().describe("Scope (default: projects)"),
3914
3949
  group_id: z6.string().optional().describe("Group path (required when scope is groups)")
3915
3950
  },
3916
3951
  execute: async (args) => {
3917
- const auth = ctx.ensureAuth();
3918
- if (!auth) throw new Error("GitLab authentication not available");
3952
+ const auth = authAndValidate(args.project_id);
3919
3953
  const { scope, id } = resolveScope2(args);
3920
3954
  const draftSlug = `${DRAFTS_PREFIX}/${args.name}`;
3921
3955
  const publishedSlug = `${SKILLS_PREFIX}/${args.name}`;