@goodtek/vibeops 2.5.2 → 3.1.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 +55 -0
- package/README.md +89 -4
- package/dist/commands/pull.js +16 -0
- package/dist/commands/task-add.js +175 -97
- package/dist/commands/task-del.js +7 -0
- package/dist/commands/task-merge.js +31 -4
- package/dist/commands/task-release.js +28 -4
- package/dist/commands/task-ship.js +7 -0
- package/dist/commands/task-sync.js +60 -28
- package/dist/lib/check-rollup.js +128 -0
- package/dist/lib/config.js +3 -0
- package/dist/lib/git-integration-sync.js +77 -71
- package/dist/lib/git-worktree.js +214 -0
- package/dist/lib/git.js +63 -54
- package/dist/lib/merge-config.js +125 -0
- package/dist/lib/merge-request-readiness.js +20 -1
- package/dist/lib/pr-create.js +293 -103
- package/dist/lib/task-del.js +7 -5
- package/dist/lib/task-id-allocation.js +192 -0
- package/dist/lib/task-lock.js +356 -0
- package/dist/lib/task-new-cycle.js +12 -1
- package/dist/lib/task-push-pr.js +7 -0
- package/dist/lib/task-reship.js +27 -12
- package/dist/lib/task-start.js +35 -26
- package/package.json +1 -1
package/dist/lib/task-start.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { relative, resolve } from "node:path";
|
|
2
2
|
import { branchNameForTaskFile, readGitContext, readTaskFile, updateInlineStatus, upsertGitContext, } from "./task.js";
|
|
3
|
-
import { gitBranchExists, gitCheckout, gitCheckoutNewBranch, gitGovernanceOnlyDirty,
|
|
3
|
+
import { gitBranchExists, gitCheckout, gitCheckoutNewBranch, gitGovernanceOnlyDirty, gitRevParse, readGitInfo, } from "./git.js";
|
|
4
|
+
import { resolveIntegrationBaseRef } from "./git-worktree.js";
|
|
4
5
|
import { ensureIntegrationSynced, printIntegrationSyncDiagnosis, } from "./git-integration-sync.js";
|
|
5
6
|
import { cyan, dim, log } from "./logger.js";
|
|
6
7
|
function relOrAbs(root, p) {
|
|
@@ -42,40 +43,48 @@ export async function startTaskBranch(opts) {
|
|
|
42
43
|
const existingCtx = await readGitContext(taskFile);
|
|
43
44
|
const branchExists = await gitBranchExists(cwd, taskBranch);
|
|
44
45
|
if (opts.dryRun) {
|
|
46
|
+
const base = (await resolveIntegrationBaseRef(cwd, remote, integrationBranch)) ??
|
|
47
|
+
`${remote}/${integrationBranch}`;
|
|
45
48
|
log.info(` ${dim("integration")} ${integrationBranch}`);
|
|
46
49
|
log.info(` ${dim("task branch")} ${cyan(taskBranch)}`);
|
|
47
50
|
log.info(dim(branchExists
|
|
48
51
|
? `dry-run — would git switch ${taskBranch}`
|
|
49
|
-
: `dry-run — would
|
|
52
|
+
: `dry-run — would git fetch ${remote} ${integrationBranch}, then git switch -c ${taskBranch} --no-track ${base}`));
|
|
50
53
|
return true;
|
|
51
54
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
// Worktree-safe (D-006): never check out the integration branch — another
|
|
56
|
+
// worktree may own it. New task branches start from <remote>/<integration>.
|
|
57
|
+
let baseRef = null;
|
|
58
|
+
if (!branchExists) {
|
|
59
|
+
if (opts.skipIntegrationPull === true) {
|
|
60
|
+
baseRef = await resolveIntegrationBaseRef(cwd, remote, integrationBranch);
|
|
57
61
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
62
|
+
else {
|
|
63
|
+
const synced = await ensureIntegrationSynced({
|
|
64
|
+
cwd,
|
|
65
|
+
remote,
|
|
66
|
+
integrationBranch,
|
|
67
|
+
fetch: true,
|
|
68
|
+
});
|
|
69
|
+
if (!synced.ok) {
|
|
70
|
+
printIntegrationSyncDiagnosis(synced.diagnosis);
|
|
71
|
+
log.blank();
|
|
72
|
+
log.info(dim(`TASK file is already created — after fixing sync, rerun ${cyan("vibeops task add")} to resume the branch (does not create a second TASK).`));
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
if (synced.pulled) {
|
|
76
|
+
log.info(dim(synced.diagnosis.summary));
|
|
77
|
+
}
|
|
78
|
+
baseRef = synced.baseRef;
|
|
72
79
|
}
|
|
73
|
-
if (
|
|
74
|
-
log.
|
|
80
|
+
if (baseRef === null) {
|
|
81
|
+
log.error(`Integration branch "${integrationBranch}" not found locally or on ${remote}. Run vibeops init or create the branch.`);
|
|
82
|
+
return false;
|
|
75
83
|
}
|
|
76
84
|
}
|
|
77
85
|
const baseBranch = integrationBranch;
|
|
78
|
-
|
|
86
|
+
// Full SHA: unambiguous base for later diff ranges (display is shortened below).
|
|
87
|
+
const baseCommit = baseRef !== null ? ((await gitRevParse(cwd, `${baseRef}^{commit}`)) ?? "") : "";
|
|
79
88
|
if (baseCommit.length === 0 && !branchExists) {
|
|
80
89
|
log.error("No commits on integration branch. Create an initial commit first.");
|
|
81
90
|
return false;
|
|
@@ -86,7 +95,7 @@ export async function startTaskBranch(opts) {
|
|
|
86
95
|
taskBranch,
|
|
87
96
|
startedAt: existingCtx?.startedAt ?? new Date().toISOString(),
|
|
88
97
|
};
|
|
89
|
-
log.info(` ${dim("integration")} ${baseBranch} @ ${ctx.baseCommit.slice(0, 7)}`);
|
|
98
|
+
log.info(` ${dim("integration")} ${baseRef ?? baseBranch} @ ${ctx.baseCommit.slice(0, 7)}`);
|
|
90
99
|
log.info(` ${dim("task branch")} ${cyan(taskBranch)}`);
|
|
91
100
|
if (branchExists) {
|
|
92
101
|
await gitCheckout(cwd, taskBranch);
|
|
@@ -99,7 +108,7 @@ export async function startTaskBranch(opts) {
|
|
|
99
108
|
log.ok(`Resumed ${taskBranch}`);
|
|
100
109
|
}
|
|
101
110
|
else {
|
|
102
|
-
await gitCheckoutNewBranch(cwd, taskBranch,
|
|
111
|
+
await gitCheckoutNewBranch(cwd, taskBranch, baseRef, { noTrack: true });
|
|
103
112
|
await updateInlineStatus(taskFile, "in_progress");
|
|
104
113
|
await upsertGitContext(taskFile, ctx);
|
|
105
114
|
log.ok(`Branch ${taskBranch} ready`);
|