@coderook/cli 0.31.4 → 0.31.5
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/.claude-plugin/plugin.json +1 -1
- package/dist/cli/src/api.js +13 -0
- package/dist/cli/src/cli.js +117 -2
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "coderook",
|
|
3
3
|
"displayName": "CodeRook",
|
|
4
4
|
"description": "Save, browse and restore whole-snapshot versions of a project on CodeRook, from Claude Code.",
|
|
5
|
-
"version": "0.31.
|
|
5
|
+
"version": "0.31.5",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ACCA Gaming Productions",
|
|
8
8
|
"url": "https://coderook.com"
|
package/dist/cli/src/api.js
CHANGED
|
@@ -10,6 +10,8 @@ exports.projects = projects;
|
|
|
10
10
|
exports.findPublicProject = findPublicProject;
|
|
11
11
|
exports.findProject = findProject;
|
|
12
12
|
exports.health = health;
|
|
13
|
+
exports.openProposal = openProposal;
|
|
14
|
+
exports.proposals = proposals;
|
|
13
15
|
exports.mergeTracks = mergeTracks;
|
|
14
16
|
exports.mergeTrack = mergeTrack;
|
|
15
17
|
exports.resolveMergeConflict = resolveMergeConflict;
|
|
@@ -265,6 +267,17 @@ async function health() {
|
|
|
265
267
|
});
|
|
266
268
|
return (await response.json());
|
|
267
269
|
}
|
|
270
|
+
/** Offer a line of work to another, usually main. */
|
|
271
|
+
async function openProposal(repositoryId, input) {
|
|
272
|
+
return call(`/v1/repositories/${repositoryId}/proposals`, {
|
|
273
|
+
method: "POST",
|
|
274
|
+
body: input,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
async function proposals(repositoryId, all = false) {
|
|
278
|
+
const body = await call(`/v1/repositories/${repositoryId}/proposals${all ? "?state=all" : ""}`);
|
|
279
|
+
return body.proposals;
|
|
280
|
+
}
|
|
268
281
|
async function mergeTracks(repositoryId) {
|
|
269
282
|
const body = await call(`/v1/repositories/${repositoryId}/merge-tracks`);
|
|
270
283
|
return body.mergeTracks;
|
package/dist/cli/src/cli.js
CHANGED
|
@@ -1026,6 +1026,17 @@ The connection failed: ${text}`));
|
|
|
1026
1026
|
observedHeadVersionId: result.versionId,
|
|
1027
1027
|
local: result.local,
|
|
1028
1028
|
manifest: result.manifest,
|
|
1029
|
+
/*
|
|
1030
|
+
The line this folder is on survives a save onto it.
|
|
1031
|
+
|
|
1032
|
+
The same fault `get` had and lost: this record is built fresh, and
|
|
1033
|
+
without naming `track` every save onto a line moved the folder back to
|
|
1034
|
+
main — so the second save on a line went to main, and `cbx propose`
|
|
1035
|
+
found the folder "on main" straight after `cbx track spike --new` and a
|
|
1036
|
+
save. A one-off `--track` does not move it either: that flag means
|
|
1037
|
+
"just this once", so the folder keeps the line it had.
|
|
1038
|
+
*/
|
|
1039
|
+
...(link?.track ? { track: link.track } : {}),
|
|
1029
1040
|
});
|
|
1030
1041
|
/*
|
|
1031
1042
|
What this save hashed, kept for the next one.
|
|
@@ -1547,6 +1558,69 @@ async function commandDoctor() {
|
|
|
1547
1558
|
* project looks untouched — so this is the way to find out that work of
|
|
1548
1559
|
* yours is sitting somewhere, still complete, waiting.
|
|
1549
1560
|
*/
|
|
1561
|
+
/**
|
|
1562
|
+
* Offer this folder's line of work to another line, usually main.
|
|
1563
|
+
*
|
|
1564
|
+
* The folder's line is the one proposed, because it is the one being worked
|
|
1565
|
+
* on; proposing main is refused rather than guessed at, since the answer to
|
|
1566
|
+
* "propose what?" is then a line nobody named.
|
|
1567
|
+
*/
|
|
1568
|
+
async function commandPropose(parsed) {
|
|
1569
|
+
const folder = folderFor(parsed);
|
|
1570
|
+
const link = await (0, config_js_1.readLink)(folder);
|
|
1571
|
+
if (!link) {
|
|
1572
|
+
console.error(red("This folder is not linked to a project on your account."));
|
|
1573
|
+
return 1;
|
|
1574
|
+
}
|
|
1575
|
+
const from = flagText(parsed, "from") ?? (await (0, track_commands_js_1.trackFor)(folder));
|
|
1576
|
+
const into = flagText(parsed, "into") ?? "main";
|
|
1577
|
+
if (from === into) {
|
|
1578
|
+
console.error(red(`This folder is on ${from}. Start a line with cbx track <name> --new, save onto it, then propose it.`));
|
|
1579
|
+
return 1;
|
|
1580
|
+
}
|
|
1581
|
+
const title = flagText(parsed, "message", "m", "title");
|
|
1582
|
+
if (!title) {
|
|
1583
|
+
console.error(red('Give it a title: cbx propose -m "What this changes"'));
|
|
1584
|
+
return 1;
|
|
1585
|
+
}
|
|
1586
|
+
const opened = await (0, api_js_1.openProposal)(link.repositoryId, {
|
|
1587
|
+
from,
|
|
1588
|
+
into,
|
|
1589
|
+
title,
|
|
1590
|
+
...(flagText(parsed, "body") ? { body: flagText(parsed, "body") } : {}),
|
|
1591
|
+
});
|
|
1592
|
+
const reference = opened.mergeTrack.reference;
|
|
1593
|
+
console.log(`${accent(reference)} ${from} → ${into} ${title}`);
|
|
1594
|
+
if (opened.conflicts.settled) {
|
|
1595
|
+
console.log(dim(` ${opened.conflicts.settled} file(s) both sides changed were combined line by line.`));
|
|
1596
|
+
}
|
|
1597
|
+
console.log(opened.conflicts.unresolved
|
|
1598
|
+
? ` ${opened.conflicts.unresolved} file(s) need a decision. Run cbx merge ${reference} to look.`
|
|
1599
|
+
: dim(` Nothing to decide. Run cbx merge ${reference} --apply when it has been reviewed.`));
|
|
1600
|
+
return 0;
|
|
1601
|
+
}
|
|
1602
|
+
async function commandProposals(parsed) {
|
|
1603
|
+
const folder = folderFor(parsed);
|
|
1604
|
+
const link = await (0, config_js_1.readLink)(folder);
|
|
1605
|
+
if (!link) {
|
|
1606
|
+
console.error(red("This folder is not linked to a project on your account."));
|
|
1607
|
+
return 1;
|
|
1608
|
+
}
|
|
1609
|
+
const listed = await (0, api_js_1.proposals)(link.repositoryId, hasFlag(parsed, "all"));
|
|
1610
|
+
if (!listed.length) {
|
|
1611
|
+
console.log(hasFlag(parsed, "all") ? "No proposals yet." : "No open proposals.");
|
|
1612
|
+
return 0;
|
|
1613
|
+
}
|
|
1614
|
+
for (const proposal of listed) {
|
|
1615
|
+
const counts = proposal.conflicts;
|
|
1616
|
+
const waiting = counts && counts.unresolved ? red(`${counts.unresolved} to decide`) : "";
|
|
1617
|
+
console.log(`${accent(proposal.reference)} ${proposal.proposal?.from ?? "?"} → ${proposal.proposal?.into ?? "?"} ` +
|
|
1618
|
+
`${proposal.proposal?.title ?? ""} ${waiting}` +
|
|
1619
|
+
(proposal.state === "open" ? "" : dim(` ${proposal.state}`)));
|
|
1620
|
+
}
|
|
1621
|
+
console.log(dim("\nRun cbx merge <reference> to look at one."));
|
|
1622
|
+
return 0;
|
|
1623
|
+
}
|
|
1550
1624
|
async function commandMerges(parsed) {
|
|
1551
1625
|
const folder = folderFor(parsed);
|
|
1552
1626
|
const link = await (0, config_js_1.readLink)(folder);
|
|
@@ -1629,6 +1703,18 @@ async function commandMerge(parsed) {
|
|
|
1629
1703
|
}
|
|
1630
1704
|
}
|
|
1631
1705
|
const now = await (0, api_js_1.mergeTrack)(summary.id);
|
|
1706
|
+
if (now.proposal) {
|
|
1707
|
+
console.log(`\n${accent(now.mergeTrack.reference)} ${now.proposal.from} → ${now.proposal.into}` +
|
|
1708
|
+
(now.changeRequest ? ` ${now.changeRequest.title}` : ""));
|
|
1709
|
+
const approvals = now.changeRequest?.approvals;
|
|
1710
|
+
if (approvals && approvals.required) {
|
|
1711
|
+
console.log(` ${approvals.satisfied ? accent("approved") : red("waiting for review")}` +
|
|
1712
|
+
dim(` · ${approvals.approvals} of ${approvals.required} approvals`));
|
|
1713
|
+
}
|
|
1714
|
+
for (const blocked of now.provisional.blockedByChecks ?? []) {
|
|
1715
|
+
console.log(` ${red("check")} ${blocked}`);
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1632
1718
|
console.log(`
|
|
1633
1719
|
${accent(now.mergeTrack.reference)} · ${now.provisional.fileCount} files · ` +
|
|
1634
1720
|
(now.provisional.ready
|
|
@@ -1646,10 +1732,14 @@ ${accent(now.mergeTrack.reference)} · ${now.provisional.fileCount} files · ` +
|
|
|
1646
1732
|
const applied = await (0, api_js_1.applyMerge)(summary.id);
|
|
1647
1733
|
console.log(`
|
|
1648
1734
|
Applied as ${accent(`v${applied.version.sequence}`)}.`);
|
|
1735
|
+
if (applied.closedIssues?.length) {
|
|
1736
|
+
console.log(`Closed ${applied.closedIssues.map((number) => `#${number}`).join(", ")}.`);
|
|
1737
|
+
}
|
|
1649
1738
|
console.log(dim("Run cbx get to bring it down to this folder."));
|
|
1650
1739
|
return 0;
|
|
1651
1740
|
}
|
|
1652
|
-
|
|
1741
|
+
const stillOpen = now.conflicts.some((conflict) => !conflict.resolvedAt);
|
|
1742
|
+
if (!decision && stillOpen) {
|
|
1653
1743
|
console.log(dim(`
|
|
1654
1744
|
--mine keeps yours, --theirs keeps what was already saved,` +
|
|
1655
1745
|
` --drop removes the file.
|
|
@@ -2197,7 +2287,7 @@ const SPECS = [
|
|
|
2197
2287
|
detail: "A signed POST to an address of yours when something happens here.\n" +
|
|
2198
2288
|
"The signing secret is generated by the service and shown once, when\n" +
|
|
2199
2289
|
"the hook is added — no route hands it back afterwards.\n\n" +
|
|
2200
|
-
"Events: version.published, merge.opened, merge.applied,\n" +
|
|
2290
|
+
"Events: version.published, merge.opened, merge.applied, merge.cancelled,\n" +
|
|
2201
2291
|
"check.reported, change_request.opened, change_request.reviewed.\n" +
|
|
2202
2292
|
"Naming none of them sends all of them.",
|
|
2203
2293
|
options: [
|
|
@@ -2552,6 +2642,31 @@ const SPECS = [
|
|
|
2552
2642
|
options: [{ flags: "--revoke <id>", description: "stop one working now" }],
|
|
2553
2643
|
run: service_commands_js_1.commandTokens,
|
|
2554
2644
|
},
|
|
2645
|
+
{
|
|
2646
|
+
name: "propose",
|
|
2647
|
+
group: "Working with a folder",
|
|
2648
|
+
summary: "offer this folder's line to main",
|
|
2649
|
+
usage: 'propose -m "title" [--into main] [--body text] [folder]',
|
|
2650
|
+
options: [
|
|
2651
|
+
{ flags: "-m, --message <text>", description: "the proposal's title" },
|
|
2652
|
+
{ flags: "--into <line>", description: "the line to propose into (default main)" },
|
|
2653
|
+
{ flags: "--from <line>", description: "propose this line instead of the folder's" },
|
|
2654
|
+
{ flags: "--body <text>", description: "a longer description" },
|
|
2655
|
+
],
|
|
2656
|
+
detail: "Opens a proposal from the line this folder is on into main (or --into).\n" +
|
|
2657
|
+
"Files both sides changed are combined line by line where they can be;\n" +
|
|
2658
|
+
"the rest wait for a decision in cbx merge. \"Fixes #12\" in the title or\n" +
|
|
2659
|
+
"body closes issue 12 when the proposal lands.",
|
|
2660
|
+
run: commandPropose,
|
|
2661
|
+
},
|
|
2662
|
+
{
|
|
2663
|
+
name: "proposals",
|
|
2664
|
+
group: "Working with a folder",
|
|
2665
|
+
summary: "open proposals on this project",
|
|
2666
|
+
usage: "proposals [--all] [folder]",
|
|
2667
|
+
options: [{ flags: "--all", description: "include merged and cancelled ones" }],
|
|
2668
|
+
run: commandProposals,
|
|
2669
|
+
},
|
|
2555
2670
|
{
|
|
2556
2671
|
name: "merges",
|
|
2557
2672
|
group: "When somebody saved first",
|