@backburner/cli 0.1.0 → 0.1.2

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.
@@ -1,6 +1,9 @@
1
1
  import { deriveOverallStatus } from "../engine.js";
2
2
  import * as path from "node:path";
3
+ import { createRequire } from "node:module";
3
4
  import { defaultBackburnerCodeRoot, defaultBackburnerManagementRoot, defaultBackburnerOutputsRoot } from "../../utils/paths.js";
5
+ const require = createRequire(import.meta.url);
6
+ const terminalQr = require("qrcode-terminal");
4
7
  export class ShowSummaryStep {
5
8
  name = "show-summary";
6
9
  description = "Summary";
@@ -62,13 +65,23 @@ export class ShowSummaryStep {
62
65
  }
63
66
  }
64
67
  if (succeeded) {
68
+ const issueTarget = buildFirstIssueTarget(ctx);
65
69
  lines.push("");
66
70
  lines.push("Next steps:");
67
- lines.push(" 1. Create the configured GitHub labels on each managed repository");
68
- lines.push(" 2. Start the orchestrator:");
71
+ lines.push(" 1. Start the orchestrator:");
69
72
  lines.push(` ${buildRunCommand(ctx)}`);
70
- lines.push(" 3. Open an issue on a managed repo and apply the 'agent-plan-approved' label");
71
- lines.push(" 4. Watch Backburner pick it up on the next orchestration cycle");
73
+ if (issueTarget !== undefined) {
74
+ lines.push(" 2. Open a Backburner issue:");
75
+ lines.push(` ${issueTarget.prefilledIssueUrl}`);
76
+ lines.push(" 3. Watch Backburner pick it up on the next orchestration cycle");
77
+ lines.push("");
78
+ lines.push("Repository issues QR:");
79
+ lines.push(renderQr(issueTarget.repositoryIssuesUrl));
80
+ }
81
+ else {
82
+ lines.push(" 2. Add a repository to repos.json");
83
+ lines.push(" 3. Open an issue on a managed repo with the configured product-approved label");
84
+ }
72
85
  }
73
86
  else {
74
87
  lines.push("");
@@ -79,6 +92,43 @@ export class ShowSummaryStep {
79
92
  return { status: "passed", message: "Summary displayed" };
80
93
  }
81
94
  }
95
+ function buildFirstIssueTarget(ctx) {
96
+ const repo = ctx.configDraft?.repos[0];
97
+ if (repo === undefined) {
98
+ return undefined;
99
+ }
100
+ const url = new URL(`https://github.com/${repo.owner}/${repo.name}/issues/new`);
101
+ url.searchParams.set("title", "Initialize a TypeScript React Native kitchen measurement converter");
102
+ url.searchParams.set("body", [
103
+ "Create a small TypeScript React Native application for converting common kitchen measurements.",
104
+ "",
105
+ "Goal:",
106
+ "- Let a cook enter a quantity, choose a source unit, choose a target unit, and see the converted value.",
107
+ "",
108
+ "Requirements:",
109
+ "- Use TypeScript.",
110
+ "- Support cups, tablespoons, teaspoons, milliliters, liters, fluid ounces, ounces, grams, and kilograms.",
111
+ "- Include a simple conversion screen with clear input validation and useful empty/error states.",
112
+ "- Keep the implementation small and easy to review.",
113
+ "",
114
+ "Acceptance criteria:",
115
+ "- The app can convert at least 1 cup to tablespoons, milliliters, and fluid ounces.",
116
+ "- Invalid or empty input does not crash the app.",
117
+ "- Add or update tests for the conversion logic where the project test setup supports it."
118
+ ].join("\n"));
119
+ url.searchParams.set("labels", repo.labels.agentProductApproved);
120
+ return {
121
+ prefilledIssueUrl: url.toString(),
122
+ repositoryIssuesUrl: `https://github.com/${repo.owner}/${repo.name}/issues`
123
+ };
124
+ }
125
+ function renderQr(input) {
126
+ let rendered = "";
127
+ terminalQr.generate(input, { small: true }, (qr) => {
128
+ rendered = qr.trimEnd();
129
+ });
130
+ return rendered;
131
+ }
82
132
  function buildRunCommand(ctx) {
83
133
  const args = ["backburner", "run"];
84
134
  if (ctx.codeRoot !== defaultBackburnerCodeRoot()) {
@@ -18,7 +18,8 @@ export class WelcomeStep {
18
18
  " 5. Detecting available AI providers",
19
19
  " 6. Assigning models to agent roles",
20
20
  " 7. Generating configuration files",
21
- " 8. Running a final readiness check",
21
+ " 8. Creating configured GitHub labels",
22
+ " 9. Running a final readiness check",
22
23
  ""
23
24
  ];
24
25
  process.stdout.write(lines.join("\n"));
@@ -18,9 +18,21 @@ export const outputsJournalRoot = path.join(outputsRoot, "journal");
18
18
  export function resolveOutputsJournalRoot(outputsDir) {
19
19
  return path.join(outputsDir, "journal");
20
20
  }
21
+ export function expandHomePath(input) {
22
+ if (input === "~") {
23
+ return os.homedir();
24
+ }
25
+ if (input.startsWith("~/") || input.startsWith("~\\")) {
26
+ return path.join(os.homedir(), input.slice(2));
27
+ }
28
+ return input;
29
+ }
30
+ export function resolveUserPath(input) {
31
+ return path.resolve(expandHomePath(input));
32
+ }
21
33
  export function defaultBackburnerRoot() {
22
34
  if (process.env.BACKBURNER_ROOT !== undefined && process.env.BACKBURNER_ROOT.trim() !== "") {
23
- return process.env.BACKBURNER_ROOT;
35
+ return resolveUserPath(process.env.BACKBURNER_ROOT);
24
36
  }
25
37
  return path.join(os.homedir(), ".backburner");
26
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backburner/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "Local GitHub-based agent orchestration CLI",
6
6
  "license": "MIT",
@@ -55,6 +55,7 @@
55
55
  "dependencies": {
56
56
  "@smithery/api": "^0.67.0",
57
57
  "cross-spawn": "^7.0.6",
58
+ "qrcode-terminal": "^0.12.0",
58
59
  "xstate": "^5.31.0",
59
60
  "zod": "^4.4.3"
60
61
  }