@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 +6 -0
- package/dist/cli.js +0 -0
- package/dist/lib/pr-create.js +20 -10
- package/dist/lib/task-pr-llm.js +15 -3
- package/package.json +12 -14
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
|
package/dist/lib/pr-create.js
CHANGED
|
@@ -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
|
|
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
|
-
"-
|
|
126
|
-
|
|
124
|
+
"-F",
|
|
125
|
+
"json",
|
|
127
126
|
"-P",
|
|
128
127
|
"1",
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
"
|
|
132
|
-
|
|
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, "
|
|
185
|
-
const
|
|
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")
|
package/dist/lib/task-pr-llm.js
CHANGED
|
@@ -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
|
|
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 {
|
|
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 =
|
|
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.
|
|
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
|
+
}
|