@helmsmith/workbrokr 0.3.0 → 0.3.1
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/SKILL.md +2 -0
- package/dist/cli.js +34 -13
- package/dist/cli.js.map +1 -1
- package/dist/core/index.js +16 -0
- package/dist/core/index.js.map +1 -1
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -65,3 +65,5 @@ work pr <area> --title "feat(area): what changed" --body-file /tmp/pr-body.md
|
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
`work pr` pushes the branch first, then opens the PR through `pritty pr --no-push --auto-approve --json` against the manifest's base branch, and stores `{ number, url, draft }` on the effort (`work status` shows it). Run it again and it returns the same PR; pass `--title`/`--body-file` again to update the PR's words in place. If the stored PR was merged or closed it refuses with `PR_CLOSED`; `--force` opens a new one. Write the body in the repository's PR conventions; the attribution footer comes from pritty's `prFooter`, not from you. Always pass a title and a body: pritty's AI path is the fallback, never the default. Needs `@helmsmith/pritty` 0.1.1 or newer on PATH.
|
|
68
|
+
|
|
69
|
+
`--story` takes a path relative to the manifest's Storybook host (`app-ui` in skoolscout): a folder, a story or module file, or a bare stem such as `components/discover-schools/dashboards/charts/ChartSkeleton` (storybrokr 0.3.1 or newer resolves a stem to its file).
|
package/dist/cli.js
CHANGED
|
@@ -165,6 +165,22 @@ var Git = class _Git {
|
|
|
165
165
|
else if (this.remoteBranchExists(this.currentBranch())) ref = `origin/${this.currentBranch()}`;
|
|
166
166
|
return this.lines(["rev-list", `${ref}..HEAD`]).length;
|
|
167
167
|
}
|
|
168
|
+
/** Non-merge commits on HEAD that origin/<base> does not have: the branch's own work (sync merges do not count). */
|
|
169
|
+
ownCommitCount(base) {
|
|
170
|
+
const r = this.tryRun(["rev-list", "--count", "--no-merges", `origin/${base}..HEAD`]);
|
|
171
|
+
return r.code === 0 ? Number(r.out.trim()) || 0 : 0;
|
|
172
|
+
}
|
|
173
|
+
/** `branch` is already in origin/<base>: an ancestor of it, patch-equivalent (squash-merged), or without own commits. */
|
|
174
|
+
branchMergedInto(branch, base) {
|
|
175
|
+
const target = `origin/${base}`;
|
|
176
|
+
if (this.isAncestor(branch, target)) return true;
|
|
177
|
+
const own = this.tryRun(["rev-list", "--count", "--no-merges", `${target}..${branch}`]);
|
|
178
|
+
if (own.code === 0 && Number(own.out.trim()) === 0) return true;
|
|
179
|
+
const cherry = this.tryRun(["cherry", target, branch]);
|
|
180
|
+
if (cherry.code !== 0) return false;
|
|
181
|
+
const lines = cherry.out.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
182
|
+
return lines.length > 0 && lines.every((l) => l.startsWith("- "));
|
|
183
|
+
}
|
|
168
184
|
/** Commits on origin/<base> that HEAD does not have (0 when the ref is unknown). */
|
|
169
185
|
behindCount(base) {
|
|
170
186
|
const r = this.tryRun(["rev-list", "--count", `HEAD..origin/${base}`]);
|
|
@@ -1630,7 +1646,7 @@ var storybrokrCli = {
|
|
|
1630
1646
|
};
|
|
1631
1647
|
|
|
1632
1648
|
// src/lib/pritty.ts
|
|
1633
|
-
var MIN_PRITTY_VERSION = "0.1.
|
|
1649
|
+
var MIN_PRITTY_VERSION = "0.1.2";
|
|
1634
1650
|
function assertPrittyVersion(client) {
|
|
1635
1651
|
const found = client.version();
|
|
1636
1652
|
if (compareSemver(found, MIN_PRITTY_VERSION) < 0) {
|
|
@@ -1696,11 +1712,11 @@ var prittyCli = {
|
|
|
1696
1712
|
}
|
|
1697
1713
|
);
|
|
1698
1714
|
}
|
|
1699
|
-
const j = lastJsonLine(
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1715
|
+
const j = lastJsonLine(r.out, "pr --check");
|
|
1716
|
+
return {
|
|
1717
|
+
open: j.open ? { number: j.open.number, url: j.open.url, draft: Boolean(j.open.draft) } : null,
|
|
1718
|
+
last: j.last ?? null
|
|
1719
|
+
};
|
|
1704
1720
|
}
|
|
1705
1721
|
};
|
|
1706
1722
|
|
|
@@ -2563,7 +2579,9 @@ async function finishEffort(ctx, o) {
|
|
|
2563
2579
|
);
|
|
2564
2580
|
}
|
|
2565
2581
|
}
|
|
2566
|
-
|
|
2582
|
+
fetchBaseOnce(ctx);
|
|
2583
|
+
const shouldPush = !o.intoArea && (g.ownCommitCount(m.baseBranch) > 0 || g.remoteBranchExists(effort.branch));
|
|
2584
|
+
if (shouldPush) {
|
|
2567
2585
|
try {
|
|
2568
2586
|
g.push(effort.branch);
|
|
2569
2587
|
} catch (err) {
|
|
@@ -2597,14 +2615,14 @@ async function finishEffort(ctx, o) {
|
|
|
2597
2615
|
ctx.registry.removeEfforts((e) => e.id === effort.id);
|
|
2598
2616
|
return {
|
|
2599
2617
|
effort: finished2,
|
|
2600
|
-
pushed:
|
|
2618
|
+
pushed: shouldPush,
|
|
2601
2619
|
parked,
|
|
2602
2620
|
mergedIntoArea: Boolean(o.intoArea),
|
|
2603
2621
|
notices
|
|
2604
2622
|
};
|
|
2605
2623
|
}
|
|
2606
2624
|
const finished = ctx.registry.updateEffort(effort.id, { state: "finished", lastActivity: now() });
|
|
2607
|
-
return { effort: finished, pushed:
|
|
2625
|
+
return { effort: finished, pushed: shouldPush, parked, notices };
|
|
2608
2626
|
}
|
|
2609
2627
|
async function reapLeases(ctx, o = {}) {
|
|
2610
2628
|
const m = ctx.manifest;
|
|
@@ -2719,10 +2737,12 @@ async function retireArea(ctx, o) {
|
|
|
2719
2737
|
const branchesDeleted = [];
|
|
2720
2738
|
const branchesKept = [];
|
|
2721
2739
|
const allAreaBranches = m.branch.types.map((type) => `${type}/${o.area}`);
|
|
2740
|
+
fetchBaseOnce(ctx);
|
|
2722
2741
|
for (const branch of allAreaBranches) {
|
|
2723
2742
|
if (!main.branchExists(branch)) continue;
|
|
2724
2743
|
const onOrigin = main.remoteBranchExists(branch) && main.tryRun(["rev-list", "--count", `origin/${branch}..${branch}`]).out.trim() === "0";
|
|
2725
|
-
|
|
2744
|
+
const mergedIntoBase = !onOrigin && main.branchMergedInto(branch, m.baseBranch);
|
|
2745
|
+
if (onOrigin || mergedIntoBase) {
|
|
2726
2746
|
main.deleteLocalBranch(branch);
|
|
2727
2747
|
branchesDeleted.push(branch);
|
|
2728
2748
|
} else branchesKept.push(branch);
|
|
@@ -2784,7 +2804,7 @@ async function prEffort(ctx, o) {
|
|
|
2784
2804
|
return updated;
|
|
2785
2805
|
};
|
|
2786
2806
|
if (effort.pr) {
|
|
2787
|
-
const open = await ctx.pritty.check({ cwd: effort.worktree, base: m.baseBranch });
|
|
2807
|
+
const { open, last } = await ctx.pritty.check({ cwd: effort.worktree, base: m.baseBranch });
|
|
2788
2808
|
if (open) {
|
|
2789
2809
|
if (!given) {
|
|
2790
2810
|
return { effort: store(open), pr: open, created: false, behindBase: behind, warnings };
|
|
@@ -2801,10 +2821,11 @@ async function prEffort(ctx, o) {
|
|
|
2801
2821
|
return { effort: store(pr2), pr: pr2, created: false, behindBase: behind, warnings };
|
|
2802
2822
|
}
|
|
2803
2823
|
if (!o.force) {
|
|
2824
|
+
const fate = last?.number === effort.pr.number ? last.state === "MERGED" ? "was merged" : "was closed without merging" : "is no longer open";
|
|
2804
2825
|
throw new WorkkitError(
|
|
2805
2826
|
"PR_CLOSED",
|
|
2806
|
-
`PR #${effort.pr.number} for ${label}
|
|
2807
|
-
{ pr: effort.pr }
|
|
2827
|
+
`PR #${effort.pr.number} for ${label} ${fate} (${effort.pr.url}); pass --force to open a new one`,
|
|
2828
|
+
{ pr: effort.pr, state: last?.state }
|
|
2808
2829
|
);
|
|
2809
2830
|
}
|
|
2810
2831
|
}
|