spets 0.1.5 → 0.1.7
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/index.js +109 -61
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1069,6 +1069,7 @@ var GitHubPlatform = class extends BasePlatform {
|
|
|
1069
1069
|
config;
|
|
1070
1070
|
currentTaskId;
|
|
1071
1071
|
currentOutputPath;
|
|
1072
|
+
lastQuestions;
|
|
1072
1073
|
constructor(config) {
|
|
1073
1074
|
super();
|
|
1074
1075
|
this.config = config;
|
|
@@ -1076,12 +1077,16 @@ var GitHubPlatform = class extends BasePlatform {
|
|
|
1076
1077
|
setTaskId(taskId) {
|
|
1077
1078
|
this.currentTaskId = taskId;
|
|
1078
1079
|
}
|
|
1080
|
+
setBranch(branch) {
|
|
1081
|
+
this.config.branch = branch;
|
|
1082
|
+
}
|
|
1079
1083
|
async generateDocument(context) {
|
|
1080
1084
|
this.currentTaskId = context.taskId;
|
|
1081
1085
|
this.currentOutputPath = context.outputPath;
|
|
1082
1086
|
const prompt = this.buildPrompt(context);
|
|
1083
1087
|
const response = await this.callClaude(prompt);
|
|
1084
1088
|
const { document, questions } = this.parseResponse(response);
|
|
1089
|
+
this.lastQuestions = questions;
|
|
1085
1090
|
return { document, questions };
|
|
1086
1091
|
}
|
|
1087
1092
|
async askUser(questions) {
|
|
@@ -1092,7 +1097,7 @@ var GitHubPlatform = class extends BasePlatform {
|
|
|
1092
1097
|
throw new PauseForInputError("questions", questions);
|
|
1093
1098
|
}
|
|
1094
1099
|
async requestApproval(doc, stepName) {
|
|
1095
|
-
const comment = this.formatApprovalComment(doc, stepName, this.currentTaskId, this.currentOutputPath);
|
|
1100
|
+
const comment = this.formatApprovalComment(doc, stepName, this.currentTaskId, this.currentOutputPath, this.lastQuestions);
|
|
1096
1101
|
await this.postComment(comment);
|
|
1097
1102
|
console.log("\n\u23F8\uFE0F Waiting for approval on GitHub...");
|
|
1098
1103
|
console.log(" Comment /approve, /revise <feedback>, or /reject on the PR/Issue.");
|
|
@@ -1143,36 +1148,59 @@ var GitHubPlatform = class extends BasePlatform {
|
|
|
1143
1148
|
lines.push("```");
|
|
1144
1149
|
return lines.join("\n");
|
|
1145
1150
|
}
|
|
1146
|
-
formatApprovalComment(doc, stepName, taskId, outputPath) {
|
|
1151
|
+
formatApprovalComment(doc, stepName, taskId, outputPath, openQuestions) {
|
|
1147
1152
|
const relativePath = outputPath ? outputPath.replace(process.cwd() + "/", "") : `.spets/outputs/${taskId}/${stepName}.md`;
|
|
1153
|
+
const { owner, repo, branch } = this.config;
|
|
1154
|
+
const fileLink = branch ? `[\`${relativePath}\`](https://github.com/${owner}/${repo}/blob/${branch}/${relativePath})` : `\`${relativePath}\``;
|
|
1155
|
+
const escapedDoc = doc.replace(/```/g, "\\`\\`\\`");
|
|
1148
1156
|
const lines = [
|
|
1149
1157
|
`## \u{1F4C4} Spets: ${stepName} - Review Required`,
|
|
1150
1158
|
"",
|
|
1151
1159
|
`> Task ID: \`${taskId}\``,
|
|
1152
|
-
`> Output:
|
|
1160
|
+
`> Output: ${fileLink}`,
|
|
1153
1161
|
"",
|
|
1154
1162
|
"<details>",
|
|
1155
1163
|
"<summary>\u{1F4DD} View Document</summary>",
|
|
1156
1164
|
"",
|
|
1157
|
-
|
|
1158
|
-
doc,
|
|
1159
|
-
"```",
|
|
1160
|
-
"",
|
|
1161
|
-
"</details>",
|
|
1162
|
-
"",
|
|
1163
|
-
"---",
|
|
1164
|
-
"",
|
|
1165
|
-
"**Commands:**",
|
|
1166
|
-
"| Command | Description |",
|
|
1167
|
-
"|---------|-------------|",
|
|
1168
|
-
"| `/approve` | Approve and continue to next step |",
|
|
1169
|
-
"| `/approve --pr` | Approve and create a Pull Request |",
|
|
1170
|
-
"| `/approve --issue` | Approve and create/update an Issue |",
|
|
1171
|
-
"| `/revise <feedback>` | Request changes with feedback |",
|
|
1172
|
-
"| `/reject` | Reject and stop workflow |",
|
|
1165
|
+
escapedDoc,
|
|
1173
1166
|
"",
|
|
1174
|
-
"
|
|
1167
|
+
"</details>"
|
|
1175
1168
|
];
|
|
1169
|
+
if (openQuestions && openQuestions.length > 0) {
|
|
1170
|
+
lines.push("");
|
|
1171
|
+
lines.push("---");
|
|
1172
|
+
lines.push("");
|
|
1173
|
+
lines.push("### \u2753 Open Questions");
|
|
1174
|
+
lines.push("");
|
|
1175
|
+
for (let i = 0; i < openQuestions.length; i++) {
|
|
1176
|
+
const q = openQuestions[i];
|
|
1177
|
+
lines.push(`**Q${i + 1}:** ${q.question}`);
|
|
1178
|
+
if (q.context) {
|
|
1179
|
+
lines.push(`> ${q.context}`);
|
|
1180
|
+
}
|
|
1181
|
+
lines.push("");
|
|
1182
|
+
}
|
|
1183
|
+
lines.push("**To answer questions:**");
|
|
1184
|
+
lines.push("```");
|
|
1185
|
+
lines.push("/answer");
|
|
1186
|
+
for (let i = 0; i < openQuestions.length; i++) {
|
|
1187
|
+
lines.push(`Q${i + 1}: <your answer>`);
|
|
1188
|
+
}
|
|
1189
|
+
lines.push("```");
|
|
1190
|
+
}
|
|
1191
|
+
lines.push("");
|
|
1192
|
+
lines.push("---");
|
|
1193
|
+
lines.push("");
|
|
1194
|
+
lines.push("**Commands:**");
|
|
1195
|
+
lines.push("| Command | Description |");
|
|
1196
|
+
lines.push("|---------|-------------|");
|
|
1197
|
+
lines.push("| `/approve` | Approve and continue to next step |");
|
|
1198
|
+
lines.push("| `/approve --pr` | Approve and create a Pull Request |");
|
|
1199
|
+
lines.push("| `/approve --issue` | Approve and create/update an Issue |");
|
|
1200
|
+
lines.push("| `/revise <feedback>` | Request changes with feedback |");
|
|
1201
|
+
lines.push("| `/reject` | Reject and stop workflow |");
|
|
1202
|
+
lines.push("");
|
|
1203
|
+
lines.push("Example: `/revise Please add more details about error handling`");
|
|
1176
1204
|
return lines.join("\n");
|
|
1177
1205
|
}
|
|
1178
1206
|
async postPRComment(body) {
|
|
@@ -1346,6 +1374,13 @@ _Managed by [Spets](https://github.com/eatnug/spets)_`;
|
|
|
1346
1374
|
}
|
|
1347
1375
|
return parseInt(match[1], 10);
|
|
1348
1376
|
}
|
|
1377
|
+
function getCurrentBranch() {
|
|
1378
|
+
try {
|
|
1379
|
+
return execSync3("git branch --show-current", { encoding: "utf-8" }).trim() || void 0;
|
|
1380
|
+
} catch {
|
|
1381
|
+
return void 0;
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1349
1384
|
function findLinkedIssueOrPR(info) {
|
|
1350
1385
|
try {
|
|
1351
1386
|
const result = execSync3(
|
|
@@ -1415,7 +1450,8 @@ async function startCommand(query, options) {
|
|
|
1415
1450
|
owner: githubInfo.owner,
|
|
1416
1451
|
repo: githubInfo.repo,
|
|
1417
1452
|
prNumber,
|
|
1418
|
-
issueNumber
|
|
1453
|
+
issueNumber,
|
|
1454
|
+
branch: getCurrentBranch()
|
|
1419
1455
|
});
|
|
1420
1456
|
console.log(`Starting workflow: ${taskId}`);
|
|
1421
1457
|
console.log(`Query: ${query}`);
|
|
@@ -1807,6 +1843,13 @@ function getGitHubInfo2(cwd) {
|
|
|
1807
1843
|
}
|
|
1808
1844
|
return null;
|
|
1809
1845
|
}
|
|
1846
|
+
function getCurrentBranch2(cwd) {
|
|
1847
|
+
try {
|
|
1848
|
+
return execSync4("git branch --show-current", { encoding: "utf-8", cwd }).trim();
|
|
1849
|
+
} catch {
|
|
1850
|
+
return void 0;
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1810
1853
|
async function githubCommand(options) {
|
|
1811
1854
|
const cwd = process.cwd();
|
|
1812
1855
|
if (!spetsExists(cwd)) {
|
|
@@ -1832,9 +1875,20 @@ async function githubCommand(options) {
|
|
|
1832
1875
|
console.log(`Received command: ${parsed.command}`);
|
|
1833
1876
|
let taskId = task;
|
|
1834
1877
|
if (!taskId) {
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1878
|
+
try {
|
|
1879
|
+
const issueNum = issue || pr;
|
|
1880
|
+
if (issueNum) {
|
|
1881
|
+
const commentsJson = execSync4(
|
|
1882
|
+
`gh api repos/${owner}/${repo}/issues/${issueNum}/comments --jq '.[].body'`,
|
|
1883
|
+
{ encoding: "utf-8" }
|
|
1884
|
+
);
|
|
1885
|
+
const taskMatch = commentsJson.match(/Task ID: `([^`]+)`/);
|
|
1886
|
+
if (taskMatch) {
|
|
1887
|
+
taskId = taskMatch[1];
|
|
1888
|
+
console.log(`Found Task ID from Issue comments: ${taskId}`);
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
} catch {
|
|
1838
1892
|
}
|
|
1839
1893
|
}
|
|
1840
1894
|
if (!taskId) {
|
|
@@ -1866,16 +1920,15 @@ async function githubCommand(options) {
|
|
|
1866
1920
|
owner,
|
|
1867
1921
|
repo,
|
|
1868
1922
|
prNumber: pr ? parseInt(pr, 10) : void 0,
|
|
1869
|
-
issueNumber: issue ? parseInt(issue, 10) : void 0
|
|
1923
|
+
issueNumber: issue ? parseInt(issue, 10) : void 0,
|
|
1924
|
+
branch: getCurrentBranch2(cwd)
|
|
1870
1925
|
};
|
|
1871
1926
|
switch (parsed.command) {
|
|
1872
1927
|
case "approve": {
|
|
1873
1928
|
console.log(`Approving step: ${state.currentStepName}`);
|
|
1874
1929
|
updateDocumentStatus(outputPath, "approved");
|
|
1875
1930
|
if (parsed.createPR) {
|
|
1876
|
-
console.log("
|
|
1877
|
-
const prNumber = await createPullRequest(githubConfig, taskId, userQuery, state.currentStepName);
|
|
1878
|
-
console.log(`Created PR #${prNumber}`);
|
|
1931
|
+
console.log("PR will be created after changes are committed.");
|
|
1879
1932
|
}
|
|
1880
1933
|
if (parsed.createIssue) {
|
|
1881
1934
|
console.log("Creating/Updating Issue...");
|
|
@@ -1972,32 +2025,8 @@ async function postComment(config, body) {
|
|
|
1972
2025
|
proc.on("error", reject);
|
|
1973
2026
|
});
|
|
1974
2027
|
}
|
|
1975
|
-
async function createPullRequest(config, taskId, userQuery, stepName) {
|
|
1976
|
-
const { execSync: execSync5 } = await import("child_process");
|
|
1977
|
-
const { owner, repo } = config;
|
|
1978
|
-
const title = userQuery.slice(0, 50) + (userQuery.length > 50 ? "..." : "");
|
|
1979
|
-
const body = `## Spets Workflow
|
|
1980
|
-
|
|
1981
|
-
- Task ID: \`${taskId}\`
|
|
1982
|
-
- Current Step: **${stepName}**
|
|
1983
|
-
|
|
1984
|
-
### Description
|
|
1985
|
-
${userQuery}
|
|
1986
|
-
|
|
1987
|
-
---
|
|
1988
|
-
_Created by [Spets](https://github.com/eatnug/spets)_`;
|
|
1989
|
-
const result = execSync5(
|
|
1990
|
-
`gh pr create --repo ${owner}/${repo} --title "${title.replace(/"/g, '\\"')}" --body "${body.replace(/"/g, '\\"')}"`,
|
|
1991
|
-
{ encoding: "utf-8" }
|
|
1992
|
-
);
|
|
1993
|
-
const match = result.match(/\/pull\/(\d+)/);
|
|
1994
|
-
if (!match) {
|
|
1995
|
-
throw new Error("Failed to parse PR number from gh output");
|
|
1996
|
-
}
|
|
1997
|
-
return parseInt(match[1], 10);
|
|
1998
|
-
}
|
|
1999
2028
|
async function createOrUpdateIssue(config, taskId, userQuery, stepName) {
|
|
2000
|
-
const {
|
|
2029
|
+
const { spawnSync } = await import("child_process");
|
|
2001
2030
|
const { owner, repo, issueNumber } = config;
|
|
2002
2031
|
const body = `## Spets Workflow Update
|
|
2003
2032
|
|
|
@@ -2010,16 +2039,35 @@ ${userQuery}
|
|
|
2010
2039
|
---
|
|
2011
2040
|
_Updated by [Spets](https://github.com/eatnug/spets)_`;
|
|
2012
2041
|
if (issueNumber) {
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2042
|
+
const result = spawnSync("gh", [
|
|
2043
|
+
"issue",
|
|
2044
|
+
"comment",
|
|
2045
|
+
String(issueNumber),
|
|
2046
|
+
"--repo",
|
|
2047
|
+
`${owner}/${repo}`,
|
|
2048
|
+
"--body",
|
|
2049
|
+
body
|
|
2050
|
+
], { encoding: "utf-8" });
|
|
2051
|
+
if (result.status !== 0) {
|
|
2052
|
+
throw new Error(`Failed to comment on issue: ${result.stderr}`);
|
|
2053
|
+
}
|
|
2017
2054
|
} else {
|
|
2018
2055
|
const title = userQuery.slice(0, 50) + (userQuery.length > 50 ? "..." : "");
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2056
|
+
const result = spawnSync("gh", [
|
|
2057
|
+
"issue",
|
|
2058
|
+
"create",
|
|
2059
|
+
"--repo",
|
|
2060
|
+
`${owner}/${repo}`,
|
|
2061
|
+
"--title",
|
|
2062
|
+
title,
|
|
2063
|
+
"--body",
|
|
2064
|
+
body,
|
|
2065
|
+
"--label",
|
|
2066
|
+
"spets"
|
|
2067
|
+
], { encoding: "utf-8" });
|
|
2068
|
+
if (result.status !== 0) {
|
|
2069
|
+
throw new Error(`Failed to create issue: ${result.stderr}`);
|
|
2070
|
+
}
|
|
2023
2071
|
}
|
|
2024
2072
|
}
|
|
2025
2073
|
|