@makerx/yoke 0.8.0 → 0.8.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/dist/cli.js +49 -25
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Command } from "commander";
|
|
|
7
7
|
// package.json
|
|
8
8
|
var package_default = {
|
|
9
9
|
name: "@makerx/yoke",
|
|
10
|
-
version: "0.8.
|
|
10
|
+
version: "0.8.1",
|
|
11
11
|
description: "Lean, user-invoked Claude Code skills for MakerX AI-assisted delivery, plus the CLI they call.",
|
|
12
12
|
license: "MIT",
|
|
13
13
|
author: "MakerX",
|
|
@@ -670,7 +670,8 @@ function renderCallerWorkflow({ inputs }) {
|
|
|
670
670
|
` uses: ${reviewWorkflowRef}`,
|
|
671
671
|
" with:",
|
|
672
672
|
...inputs.map(([name, value]) => ` ${name}: ${yamlValue(value)}`),
|
|
673
|
-
" secrets:
|
|
673
|
+
" secrets:",
|
|
674
|
+
...ciSecrets.map((secret2) => ` ${secret2}: \${{ secrets.${secret2} }}`),
|
|
674
675
|
""
|
|
675
676
|
].join("\n");
|
|
676
677
|
}
|
|
@@ -912,10 +913,22 @@ function formatSynthesis({ summary, findings }) {
|
|
|
912
913
|
return lines.join("\n").trimEnd();
|
|
913
914
|
}
|
|
914
915
|
|
|
915
|
-
// src/features/review/
|
|
916
|
+
// src/features/review/diff.ts
|
|
916
917
|
var fileHeader = /^\+\+\+ (.+)$/;
|
|
917
918
|
var hunkHeader = /^@@ -\d+(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
|
|
918
|
-
var
|
|
919
|
+
var escapes = { a: 7, b: 8, t: 9, n: 10, v: 11, f: 12, r: 13 };
|
|
920
|
+
function parseDiff(diff) {
|
|
921
|
+
let file = null;
|
|
922
|
+
const hunk = { next: 0, oldLeft: 0, newLeft: 0 };
|
|
923
|
+
return diff.split("\n").map((text2) => {
|
|
924
|
+
if (hunk.oldLeft > 0 || hunk.newLeft > 0) return { text: text2, file, line: hunkLine(text2, hunk) };
|
|
925
|
+
const header = text2.match(fileHeader)?.[1];
|
|
926
|
+
if (header) file = header === "/dev/null" ? null : diffPath(header);
|
|
927
|
+
const range = text2.match(hunkHeader);
|
|
928
|
+
if (range) Object.assign(hunk, { oldLeft: Number(range[1] ?? 1), next: Number(range[2]), newLeft: Number(range[3] ?? 1) });
|
|
929
|
+
return { text: text2, file, line: null };
|
|
930
|
+
});
|
|
931
|
+
}
|
|
919
932
|
function hunkLine(text2, hunk) {
|
|
920
933
|
if (text2.startsWith("-")) hunk.oldLeft--;
|
|
921
934
|
else if (text2.startsWith("+")) hunk.newLeft--;
|
|
@@ -925,33 +938,42 @@ function hunkLine(text2, hunk) {
|
|
|
925
938
|
} else return null;
|
|
926
939
|
return text2.startsWith("-") ? null : hunk.next++;
|
|
927
940
|
}
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
const
|
|
931
|
-
|
|
932
|
-
return Buffer.from([escapes[code] ?? code.charCodeAt(0)]);
|
|
941
|
+
function diffPath(raw) {
|
|
942
|
+
const quoted = raw.match(/^"(.*)"$/)?.[1];
|
|
943
|
+
const path = quoted === void 0 ? raw : unquote(quoted);
|
|
944
|
+
return path.startsWith("b/") ? path.slice(2) : path;
|
|
933
945
|
}
|
|
934
946
|
function unquote(quoted) {
|
|
935
947
|
const parts = quoted.split(/(\\[0-7]{3}|\\.)/);
|
|
936
948
|
return Buffer.concat(parts.map((part, i) => i % 2 ? escapedBytes(part) : Buffer.from(part))).toString("utf8");
|
|
937
949
|
}
|
|
938
|
-
function
|
|
939
|
-
const
|
|
940
|
-
|
|
941
|
-
return
|
|
950
|
+
function escapedBytes(escape) {
|
|
951
|
+
const code = escape.slice(1);
|
|
952
|
+
if (/^[0-7]{3}$/.test(code)) return Buffer.from([parseInt(code, 8)]);
|
|
953
|
+
return Buffer.from([escapes[code] ?? code.charCodeAt(0)]);
|
|
942
954
|
}
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
const header = text2.match(fileHeader)?.[1];
|
|
949
|
-
if (header) file = header === "/dev/null" ? null : diffPath(header);
|
|
950
|
-
const range = text2.match(hunkHeader);
|
|
951
|
-
if (range) Object.assign(hunk, { oldLeft: Number(range[1] ?? 1), next: Number(range[2]), newLeft: Number(range[3] ?? 1) });
|
|
952
|
-
return { text: text2, file, line: null };
|
|
953
|
-
});
|
|
955
|
+
|
|
956
|
+
// src/features/review/selfReviewNote.ts
|
|
957
|
+
var yokeCaller = /\buses:\s*['"]?MakerXStudio\/yoke\/\.github\/workflows\/review\.yml@/i;
|
|
958
|
+
function editsYokeCaller(diff) {
|
|
959
|
+
return parseDiff(diff).some(({ text: text2, file, line }) => line !== null && file?.startsWith(".github/workflows/") && yokeCaller.test(text2));
|
|
954
960
|
}
|
|
961
|
+
function selfReviewNote(diff) {
|
|
962
|
+
if (!editsYokeCaller(diff)) return "";
|
|
963
|
+
return `## Yoke's own review workflow
|
|
964
|
+
|
|
965
|
+
This change adds or edits a workflow that calls \`MakerXStudio/yoke/.github/workflows/review.yml\`, the CI setup for this review. Review it like any other file, but these are yoke's deliberate design: do not raise them as findings, keep them in a consolidated review, or mention them in a summary.
|
|
966
|
+
|
|
967
|
+
- Calling the workflow at \`@main\` rather than a tag or SHA.
|
|
968
|
+
- The trigger types, including leaving out \`synchronize\`: a review is re-run by marking the PR as draft and then ready for review.
|
|
969
|
+
- Draft PRs being reviewed twice: the reusable workflow already skips drafts.
|
|
970
|
+
|
|
971
|
+
Real defects in it are still findings, such as passing every secret with \`secrets: inherit\` instead of only \`REVIEW_CI_BASE_URL\` and \`REVIEW_CI_API_KEY\`, or an input the reusable workflow does not declare.
|
|
972
|
+
`;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
// src/features/review/request.ts
|
|
976
|
+
var gutterWidth = 6;
|
|
955
977
|
function gutter(line) {
|
|
956
978
|
return `${(line === null ? "" : String(line)).padStart(gutterWidth)} `;
|
|
957
979
|
}
|
|
@@ -970,6 +992,7 @@ function commentableLines(diff) {
|
|
|
970
992
|
function buildRequest(pr2, diff, prior = []) {
|
|
971
993
|
const files = pr2.files.map((f) => `- ${f.path}`).join("\n") || "(none)";
|
|
972
994
|
const priorSection = formatPriorComments(prior);
|
|
995
|
+
const note = selfReviewNote(diff);
|
|
973
996
|
return `# Code review request
|
|
974
997
|
|
|
975
998
|
- PR: #${pr2.number} ${pr2.title}
|
|
@@ -987,7 +1010,8 @@ Each added or context line is prefixed with a left gutter showing its line numbe
|
|
|
987
1010
|
\`\`\`diff
|
|
988
1011
|
${withNewFileLineNumbers(diff.trimEnd())}
|
|
989
1012
|
\`\`\`
|
|
990
|
-
${
|
|
1013
|
+
${note && `
|
|
1014
|
+
${note}`}${priorSection && `
|
|
991
1015
|
${priorSection}`}`;
|
|
992
1016
|
}
|
|
993
1017
|
|