spets 0.1.5 → 0.1.6

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.
Files changed (2) hide show
  1. package/dist/index.js +95 -58
  2. 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: \`${relativePath}\``,
1160
+ `> Output: ${fileLink}`,
1153
1161
  "",
1154
1162
  "<details>",
1155
1163
  "<summary>\u{1F4DD} View Document</summary>",
1156
1164
  "",
1157
- "```markdown",
1158
- doc,
1159
- "```",
1160
- "",
1161
- "</details>",
1162
- "",
1163
- "---",
1165
+ escapedDoc,
1164
1166
  "",
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 |",
1173
- "",
1174
- "Example: `/revise Please add more details about error handling`"
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)) {
@@ -1866,16 +1909,15 @@ async function githubCommand(options) {
1866
1909
  owner,
1867
1910
  repo,
1868
1911
  prNumber: pr ? parseInt(pr, 10) : void 0,
1869
- issueNumber: issue ? parseInt(issue, 10) : void 0
1912
+ issueNumber: issue ? parseInt(issue, 10) : void 0,
1913
+ branch: getCurrentBranch2(cwd)
1870
1914
  };
1871
1915
  switch (parsed.command) {
1872
1916
  case "approve": {
1873
1917
  console.log(`Approving step: ${state.currentStepName}`);
1874
1918
  updateDocumentStatus(outputPath, "approved");
1875
1919
  if (parsed.createPR) {
1876
- console.log("Creating Pull Request...");
1877
- const prNumber = await createPullRequest(githubConfig, taskId, userQuery, state.currentStepName);
1878
- console.log(`Created PR #${prNumber}`);
1920
+ console.log("PR will be created after changes are committed.");
1879
1921
  }
1880
1922
  if (parsed.createIssue) {
1881
1923
  console.log("Creating/Updating Issue...");
@@ -1972,32 +2014,8 @@ async function postComment(config, body) {
1972
2014
  proc.on("error", reject);
1973
2015
  });
1974
2016
  }
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
2017
  async function createOrUpdateIssue(config, taskId, userQuery, stepName) {
2000
- const { execSync: execSync5 } = await import("child_process");
2018
+ const { spawnSync } = await import("child_process");
2001
2019
  const { owner, repo, issueNumber } = config;
2002
2020
  const body = `## Spets Workflow Update
2003
2021
 
@@ -2010,16 +2028,35 @@ ${userQuery}
2010
2028
  ---
2011
2029
  _Updated by [Spets](https://github.com/eatnug/spets)_`;
2012
2030
  if (issueNumber) {
2013
- execSync5(
2014
- `gh issue comment ${issueNumber} --repo ${owner}/${repo} --body "${body.replace(/"/g, '\\"')}"`,
2015
- { encoding: "utf-8" }
2016
- );
2031
+ const result = spawnSync("gh", [
2032
+ "issue",
2033
+ "comment",
2034
+ String(issueNumber),
2035
+ "--repo",
2036
+ `${owner}/${repo}`,
2037
+ "--body",
2038
+ body
2039
+ ], { encoding: "utf-8" });
2040
+ if (result.status !== 0) {
2041
+ throw new Error(`Failed to comment on issue: ${result.stderr}`);
2042
+ }
2017
2043
  } else {
2018
2044
  const title = userQuery.slice(0, 50) + (userQuery.length > 50 ? "..." : "");
2019
- execSync5(
2020
- `gh issue create --repo ${owner}/${repo} --title "${title.replace(/"/g, '\\"')}" --body "${body.replace(/"/g, '\\"')}" --label spets`,
2021
- { encoding: "utf-8" }
2022
- );
2045
+ const result = spawnSync("gh", [
2046
+ "issue",
2047
+ "create",
2048
+ "--repo",
2049
+ `${owner}/${repo}`,
2050
+ "--title",
2051
+ title,
2052
+ "--body",
2053
+ body,
2054
+ "--label",
2055
+ "spets"
2056
+ ], { encoding: "utf-8" });
2057
+ if (result.status !== 0) {
2058
+ throw new Error(`Failed to create issue: ${result.stderr}`);
2059
+ }
2023
2060
  }
2024
2061
  }
2025
2062
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spets",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Spec Driven Development Execution Framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",