@goodtek/vibeops 2.4.3 → 2.5.0
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 +20 -0
- package/README.md +10 -10
- package/dist/cli.js +9 -29
- package/dist/commands/init.js +43 -21
- package/dist/commands/status.js +91 -72
- package/dist/commands/task-merge.js +23 -5
- package/dist/commands/task-release.js +19 -9
- package/dist/commands/task-sync.js +5 -3
- package/dist/lib/git-host-cli.js +115 -0
- package/dist/lib/git-remote.js +177 -59
- package/dist/lib/merge-request-readiness.js +57 -0
- package/dist/lib/pr-create.js +103 -12
- package/dist/lib/task-context.js +28 -16
- package/dist/lib/task-push-pr.js +6 -2
- package/dist/lib/task-reship.js +1 -1
- package/package.json +14 -12
- package/templates/core/AGENTS.md +1 -1
- package/templates/core/docs/project/06-decisions.md +1 -1
- package/dist/commands/task-reship.js +0 -21
package/dist/lib/task-context.js
CHANGED
|
@@ -49,7 +49,7 @@ export function computeNextHint(input) {
|
|
|
49
49
|
if (input.hasMergeRequest && !input.mergeRequestMerged)
|
|
50
50
|
return "task-merge";
|
|
51
51
|
if (input.hasLocalChanges)
|
|
52
|
-
return "task-
|
|
52
|
+
return "task-ship-followup";
|
|
53
53
|
return "task-add";
|
|
54
54
|
}
|
|
55
55
|
if (!input.resultFilled || !input.testFilled) {
|
|
@@ -57,36 +57,48 @@ export function computeNextHint(input) {
|
|
|
57
57
|
}
|
|
58
58
|
return input.hasMergeRequest ? "task-merge" : "task-ship";
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
/** Multi-line NEXT block lines (without the leading arrow prefix). */
|
|
61
|
+
export function hintToLines(hint, cwd, task) {
|
|
61
62
|
switch (hint) {
|
|
62
63
|
case "init":
|
|
63
|
-
return "
|
|
64
|
+
return ["vibeops init"];
|
|
64
65
|
case "task-add":
|
|
65
|
-
return "
|
|
66
|
+
return ["vibeops task add"];
|
|
66
67
|
case "task-ship":
|
|
67
|
-
return task ? `
|
|
68
|
-
case "task-
|
|
68
|
+
return [task ? `vibeops task ship ${task.id}` : "vibeops task ship"];
|
|
69
|
+
case "task-ship-followup":
|
|
69
70
|
return task
|
|
70
|
-
?
|
|
71
|
-
|
|
71
|
+
? [
|
|
72
|
+
`Follow up on ${task.id} (after merge: confirm or --new-cycle)`,
|
|
73
|
+
`vibeops task ship ${task.id}`,
|
|
74
|
+
]
|
|
75
|
+
: ["vibeops task ship --new-cycle"];
|
|
72
76
|
case "task-merge":
|
|
73
77
|
return task
|
|
74
|
-
? `
|
|
75
|
-
: "
|
|
78
|
+
? [`vibeops task merge ${task.id}`, "(or merge in the host UI)"]
|
|
79
|
+
: ["vibeops task merge"];
|
|
76
80
|
case "task-sync":
|
|
77
81
|
return task
|
|
78
|
-
? `
|
|
79
|
-
: "
|
|
82
|
+
? [`vibeops task sync ${task.id}`, "then: vibeops task add"]
|
|
83
|
+
: ["vibeops task sync"];
|
|
80
84
|
case "cursor-plan":
|
|
81
85
|
return task
|
|
82
|
-
?
|
|
83
|
-
|
|
86
|
+
? [
|
|
87
|
+
`Cursor Ask: @${relPath(cwd, task.filePath)} — refine Scope / AC`,
|
|
88
|
+
]
|
|
89
|
+
: ["Open the TASK file in Cursor Ask"];
|
|
84
90
|
case "cursor-implement":
|
|
85
91
|
return task
|
|
86
|
-
?
|
|
87
|
-
|
|
92
|
+
? [
|
|
93
|
+
`Cursor Agent: @${relPath(cwd, task.filePath)} — implement`,
|
|
94
|
+
`then: vibeops task ship ${task.id}`,
|
|
95
|
+
]
|
|
96
|
+
: ["Implement per the TASK file, then vibeops task ship"];
|
|
88
97
|
}
|
|
89
98
|
}
|
|
99
|
+
export function hintToText(hint, cwd, task) {
|
|
100
|
+
return hintToLines(hint, cwd, task).join(" · ");
|
|
101
|
+
}
|
|
90
102
|
export async function listInProgressTasks(paths) {
|
|
91
103
|
return (await loadActionableTasks(paths.docsTasks)).filter((t) => t.status === "in_progress");
|
|
92
104
|
}
|
package/dist/lib/task-push-pr.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatHostCliHint, formatHostCliMissingMessage } from "./git-host-cli.js";
|
|
1
2
|
import { readText } from "./filesystem.js";
|
|
2
3
|
import { readConfig } from "./config.js";
|
|
3
4
|
import { detectGitHost, mergeRequestLabel } from "./git-host.js";
|
|
@@ -94,8 +95,11 @@ export async function finishTaskWithPullRequest(opts) {
|
|
|
94
95
|
}
|
|
95
96
|
const cliOk = await probeMergeRequestCli(gitCfg.host);
|
|
96
97
|
if (!cliOk) {
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
log.warn(formatHostCliMissingMessage(gitCfg.host, `create the ${label}`));
|
|
99
|
+
for (const line of formatHostCliHint(gitCfg.host)) {
|
|
100
|
+
log.info(dim(` ${line}`));
|
|
101
|
+
}
|
|
102
|
+
log.info(dim(`Create the ${label} manually: ${gitCtx.taskBranch} → ${gitCtx.baseBranch}`));
|
|
99
103
|
return { ok: true, pushed: true };
|
|
100
104
|
}
|
|
101
105
|
const config = await readConfig(opts.cwd);
|
package/dist/lib/task-reship.js
CHANGED
|
@@ -43,7 +43,7 @@ export function reshipNotFoundMessage(taskRef) {
|
|
|
43
43
|
if (taskRef?.trim()) {
|
|
44
44
|
return `Shipped TASK not found: ${normalizeTaskRef(taskRef)}. Check docs/tasks/.`;
|
|
45
45
|
}
|
|
46
|
-
return "No Shipped TASK found. Pass `vibeops task
|
|
46
|
+
return "No Shipped TASK found. Pass `vibeops task ship TASK-NNN` (use --new-cycle after merge).";
|
|
47
47
|
}
|
|
48
48
|
async function switchToTaskBranch(cwd, taskBranch) {
|
|
49
49
|
try {
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodtek/vibeops",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Minimal CLI rails for Cursor-based TASK-driven vibe coding.",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"packageManager": "pnpm@9.15.9",
|
|
6
7
|
"author": "VibeOps contributors",
|
|
7
8
|
"license": "MIT",
|
|
8
9
|
"repository": {
|
|
@@ -29,6 +30,17 @@
|
|
|
29
30
|
"engines": {
|
|
30
31
|
"node": ">=20"
|
|
31
32
|
},
|
|
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
|
+
},
|
|
32
44
|
"keywords": [
|
|
33
45
|
"cursor",
|
|
34
46
|
"ai",
|
|
@@ -47,15 +59,5 @@
|
|
|
47
59
|
"@types/node": "^20.14.0",
|
|
48
60
|
"tsx": "^4.19.0",
|
|
49
61
|
"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"
|
|
60
62
|
}
|
|
61
|
-
}
|
|
63
|
+
}
|
package/templates/core/AGENTS.md
CHANGED
|
@@ -40,5 +40,5 @@ vibeops llm connect # optional — task add / ship
|
|
|
40
40
|
|
|
41
41
|
- One **In Progress** TASK at a time; **Shipped** does not block `task add`.
|
|
42
42
|
- Fill **Result** and **Test Result** before `vibeops task ship` (warned, not blocked, when updating an open PR).
|
|
43
|
-
- `ship` is state-aware: re-run it to update an open PR; after merge it needs `--new-cycle` (or a confirm) to start a new PR cycle.
|
|
43
|
+
- `ship` is state-aware: re-run it to update an open PR; after merge it needs `--new-cycle` (or a confirm) to start a new PR cycle.
|
|
44
44
|
- Agents do not run `task merge` or `task sync` unless the human asks.
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
## D-001 · VibeOps workflow
|
|
6
6
|
|
|
7
7
|
- **Date:** {{CREATED_AT}}
|
|
8
|
-
- **Decision:** TASK-driven development with `vibeops task add` / `task ship` / `
|
|
8
|
+
- **Decision:** TASK-driven development with `vibeops task add` / `task ship` / `merge` / `sync` and Cursor for plan/build. TASK status: **In Progress** → **Shipped** only.
|
|
9
9
|
- **Why:** Git `docs/tasks` beats chat as source of truth.
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { dim, log, yellow } from "../lib/logger.js";
|
|
2
|
-
import { taskShipCommand } from "./task-ship.js";
|
|
3
|
-
/**
|
|
4
|
-
* @deprecated `reship` is now `vibeops task ship --new-cycle`.
|
|
5
|
-
* Kept as a thin alias for backward compatibility.
|
|
6
|
-
*/
|
|
7
|
-
export async function taskReshipCommand(taskRef, options = {}) {
|
|
8
|
-
log.warn(`${yellow("reship is now `ship` (deprecated alias)")} — delegating to \`vibeops task ship --new-cycle\`.`);
|
|
9
|
-
log.info(dim("Run `vibeops task ship` directly; it detects first submit / open-PR update / new PR cycle."));
|
|
10
|
-
log.blank();
|
|
11
|
-
await taskShipCommand(taskRef, {
|
|
12
|
-
dryRun: options.dryRun,
|
|
13
|
-
cwd: options.cwd,
|
|
14
|
-
noPr: options.noPr,
|
|
15
|
-
newCycle: true,
|
|
16
|
-
noIntegrate: options.noIntegrate,
|
|
17
|
-
recreateBranch: options.recreateBranch,
|
|
18
|
-
skipLlm: options.skipLlm,
|
|
19
|
-
allowOpenMr: options.allowOpenMr,
|
|
20
|
-
});
|
|
21
|
-
}
|