@goodtek/vibeops 2.4.0 → 2.4.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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to VibeOps are documented here.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 2.4.2 - 2026-06-24
8
+
9
+ ### Fixed
10
+
11
+ - **GitLab (`glab` 1.105+):** `task merge` / `task ship` now resolve merge requests using `-F json` and `-M`/`-c`/`-A` state filters instead of deprecated `--output` / `-S` flags.
12
+
7
13
  ## 2.4.0 - 2026-06-12
8
14
 
9
15
  ### Changed
package/dist/cli.js CHANGED
File without changes
@@ -114,22 +114,31 @@ async function ghFindMergeRequestByBranches(opts) {
114
114
  }
115
115
  async function glabFindMergeRequestByBranches(opts) {
116
116
  const state = opts.state ?? "open";
117
- const glabState = state === "open" ? "opened" : state === "merged" ? "merged" : state === "closed" ? "closed" : "all";
118
- const { stdout } = await execFileAsync("glab", [
117
+ const args = [
119
118
  "mr",
120
119
  "list",
121
120
  "--source-branch",
122
121
  opts.headBranch,
123
122
  "--target-branch",
124
123
  opts.baseBranch,
125
- "-S",
126
- glabState,
124
+ "-F",
125
+ "json",
127
126
  "-P",
128
127
  "1",
129
- "--output",
130
- "json",
131
- "web_url,state",
132
- ], { cwd: opts.cwd, maxBuffer: 1024 * 1024 });
128
+ ];
129
+ if (state === "merged") {
130
+ args.push("-M");
131
+ }
132
+ else if (state === "closed") {
133
+ args.push("-c");
134
+ }
135
+ else if (state === "all") {
136
+ args.push("-A");
137
+ }
138
+ const { stdout } = await execFileAsync("glab", args, {
139
+ cwd: opts.cwd,
140
+ maxBuffer: 1024 * 1024,
141
+ });
133
142
  const trimmed = stdout.trim();
134
143
  if (trimmed.length === 0 || trimmed === "[]")
135
144
  return null;
@@ -181,8 +190,9 @@ export async function getMergeRequestState(cwd, host, url) {
181
190
  const ref = prRefFromUrl(url);
182
191
  try {
183
192
  if (host === "gitlab") {
184
- const { stdout } = await execFileAsync("glab", ["mr", "view", ref, "--output", "json", "state"], { cwd, maxBuffer: 1024 * 1024 });
185
- const state = stdout.trim().toLowerCase();
193
+ const { stdout } = await execFileAsync("glab", ["mr", "view", ref, "-F", "json"], { cwd, maxBuffer: 1024 * 1024 });
194
+ const parsed = JSON.parse(stdout.trim());
195
+ const state = (parsed.state ?? "").toLowerCase();
186
196
  if (state === "merged")
187
197
  return "merged";
188
198
  if (state === "opened" || state === "open")
@@ -1,8 +1,17 @@
1
1
  import { llmCompleteJson } from "./llm-complete.js";
2
+ import { taskScopedCommitMessage } from "./task-git-commit.js";
2
3
  const SYSTEM = `You write pull/merge request titles and bodies for a software task.
3
4
  Output valid JSON only: { "title": string, "body": string }.
4
- Title: under 72 chars, include task id.
5
+ Title: Conventional Commits format — type(task-nnn): lowercase subject (under 72 chars total).
6
+ Use task id as scope in lowercase (e.g. feat(task-013): ship public status page).
7
+ Allowed types: feat, fix, docs, chore, perf, ci, refactor, test, build, style, revert.
5
8
  Body: markdown with Summary, Changes, Test plan sections. Facts only from the input.`;
9
+ /** Normalize PR titles to Conventional Commits with the TASK id as scope. */
10
+ export function normalizeTaskPrTitle(taskId, rawTitle) {
11
+ const trimmed = rawTitle.trim().replace(/\s+/g, " ");
12
+ const withoutTaskPrefix = trimmed.replace(/^TASK-\d+\s*[:\-]\s*/i, "").trim();
13
+ return taskScopedCommitMessage(taskId, withoutTaskPrefix || trimmed).slice(0, 72);
14
+ }
6
15
  export async function generateTaskPrWithLlm(input, cwd, preference) {
7
16
  const user = [
8
17
  `Task: ${input.taskId}`,
@@ -27,14 +36,17 @@ export async function generateTaskPrWithLlm(input, cwd, preference) {
27
36
  const prBody = typeof parsed.body === "string" ? parsed.body.trim() : "";
28
37
  if (!prTitle || !prBody)
29
38
  return null;
30
- return { prTitle, prBody };
39
+ return {
40
+ prTitle: normalizeTaskPrTitle(input.taskId, prTitle),
41
+ prBody,
42
+ };
31
43
  }
32
44
  catch {
33
45
  return null;
34
46
  }
35
47
  }
36
48
  export function fallbackTaskPr(input) {
37
- const prTitle = `${input.taskId}: ${input.title}`.slice(0, 72);
49
+ const prTitle = normalizeTaskPrTitle(input.taskId, input.title);
38
50
  const prBody = [
39
51
  "## Summary",
40
52
  input.title,
package/package.json CHANGED
@@ -1,9 +1,8 @@
1
1
  {
2
2
  "name": "@goodtek/vibeops",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "Minimal CLI rails for Cursor-based TASK-driven vibe coding.",
5
5
  "type": "module",
6
- "packageManager": "pnpm@9.15.9",
7
6
  "author": "VibeOps contributors",
8
7
  "license": "MIT",
9
8
  "repository": {
@@ -30,17 +29,6 @@
30
29
  "engines": {
31
30
  "node": ">=20"
32
31
  },
33
- "scripts": {
34
- "dev": "tsx src/cli.ts",
35
- "build": "tsc -p tsconfig.json",
36
- "typecheck": "tsc -p tsconfig.json --noEmit",
37
- "start": "node dist/cli.js",
38
- "test": "pnpm build && node --test \"tests/*.test.mjs\"",
39
- "smoke": "pnpm typecheck && pnpm build && node --test \"tests/*.test.mjs\" && node scripts/smoke.mjs",
40
- "clean": "rm -rf dist",
41
- "prepack": "pnpm clean && pnpm build",
42
- "publish:dry": "pnpm publish --dry-run --no-git-checks"
43
- },
44
32
  "keywords": [
45
33
  "cursor",
46
34
  "ai",
@@ -59,5 +47,15 @@
59
47
  "@types/node": "^20.14.0",
60
48
  "tsx": "^4.19.0",
61
49
  "typescript": "^5.5.4"
50
+ },
51
+ "scripts": {
52
+ "dev": "tsx src/cli.ts",
53
+ "build": "tsc -p tsconfig.json",
54
+ "typecheck": "tsc -p tsconfig.json --noEmit",
55
+ "start": "node dist/cli.js",
56
+ "test": "pnpm build && node --test \"tests/*.test.mjs\"",
57
+ "smoke": "pnpm typecheck && pnpm build && node --test \"tests/*.test.mjs\" && node scripts/smoke.mjs",
58
+ "clean": "rm -rf dist",
59
+ "publish:dry": "pnpm publish --dry-run --no-git-checks"
62
60
  }
63
- }
61
+ }