@snipcodeit/mgw 0.1.3 → 0.2.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/bin/mgw.cjs CHANGED
@@ -1,16 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- var claude = require('../claude-Dk1oVsaG.cjs');
4
+ var index = require('../index-CXfe9U4l.cjs');
5
5
  var require$$0 = require('commander');
6
6
  var require$$1 = require('path');
7
7
  var require$$0$2 = require('fs');
8
8
  var require$$0$1 = require('child_process');
9
+ require('events');
9
10
 
10
11
  var mgw$1 = {};
11
12
 
12
- var version = "0.1.3";
13
- var require$$8 = {
13
+ var version = "0.2.1";
14
+ var require$$10 = {
14
15
  version: version};
15
16
 
16
17
  var hasRequiredMgw;
@@ -22,26 +23,85 @@ function requireMgw () {
22
23
  const path = require$$1;
23
24
  const fs = require$$0$2;
24
25
  const { execSync } = require$$0$1;
25
- const { assertClaudeAvailable, invokeClaude, getCommandsDir } = claude.requireClaude();
26
- const { log, error, formatJson, verbose } = claude.requireOutput();
27
- const { getActiveDir, getCompletedDir, getMgwDir } = claude.requireState();
28
- const { getIssue, listIssues } = claude.requireGithub();
29
- const pkg = require$$8;
26
+ const { assertClaudeAvailable, invokeClaude, getCommandsDir } = index.requireClaude();
27
+ const { log, error, formatJson, verbose } = index.requireOutput();
28
+ const { getActiveDir, getCompletedDir, getMgwDir } = index.requireState();
29
+ const { getIssue, listIssues } = index.requireGithub();
30
+ const { createIssuesBrowser } = index.requireTui();
31
+ const { createSpinner } = index.requireSpinner();
32
+ const pkg = require$$10;
30
33
  const program = new Command();
31
34
  program.name("mgw").description("GitHub issue pipeline automation \u2014 Day 1 idea to Go Live").version(pkg.version).option("--dry-run", "show what would happen without executing").option("--json", "output structured JSON").option("-v, --verbose", "show API calls and file writes").option("--debug", "full payloads and timings").option("--model <model>", "Claude model override");
35
+ const STAGE_LABELS = {
36
+ run: "pipeline",
37
+ init: "init",
38
+ project: "project",
39
+ milestone: "milestone",
40
+ issue: "triage",
41
+ pr: "create-pr",
42
+ update: "update",
43
+ next: "next"
44
+ };
32
45
  async function runAiCommand(commandName, userPrompt, opts) {
33
46
  assertClaudeAvailable();
34
47
  const cmdFile = path.join(getCommandsDir(), `${commandName}.md`);
35
- const result = await invokeClaude(cmdFile, userPrompt, {
36
- model: opts.model,
37
- quiet: opts.quiet,
38
- dryRun: opts.dryRun,
39
- json: opts.json
40
- });
41
- process.exitCode = result.exitCode;
48
+ const stageLabel = STAGE_LABELS[commandName] || commandName;
49
+ if (opts.quiet) {
50
+ const spinner = createSpinner(`mgw:${stageLabel}`);
51
+ spinner.start();
52
+ let result;
53
+ try {
54
+ result = await invokeClaude(cmdFile, userPrompt, {
55
+ model: opts.model,
56
+ quiet: true,
57
+ dryRun: opts.dryRun,
58
+ json: opts.json
59
+ });
60
+ } catch (err) {
61
+ spinner.fail(`${stageLabel} failed`);
62
+ throw err;
63
+ }
64
+ if (result.exitCode === 0) {
65
+ spinner.succeed(`${stageLabel} complete`);
66
+ } else {
67
+ spinner.fail(`${stageLabel} failed (exit ${result.exitCode})`);
68
+ }
69
+ if (result.output) {
70
+ process.stdout.write(result.output);
71
+ }
72
+ process.exitCode = result.exitCode;
73
+ } else {
74
+ const spinner = createSpinner(`mgw:${stageLabel}`);
75
+ spinner.start();
76
+ await new Promise((r) => setTimeout(r, 80));
77
+ spinner.stop();
78
+ const result = await invokeClaude(cmdFile, userPrompt, {
79
+ model: opts.model,
80
+ quiet: false,
81
+ dryRun: opts.dryRun,
82
+ json: opts.json
83
+ });
84
+ process.exitCode = result.exitCode;
85
+ }
42
86
  }
87
+ const RUN_PIPELINE_STAGES = [
88
+ "validate",
89
+ "triage",
90
+ "create-worktree",
91
+ "execute-gsd",
92
+ "create-pr"
93
+ ];
43
94
  program.command("run <issue-number>").description("Run the full pipeline for an issue").option("--quiet", "buffer output, show summary at end").option("--auto", "phase chaining: discuss -> plan -> execute").action(async function(issueNumber) {
44
95
  const opts = this.optsWithGlobals();
96
+ if (!opts.json) {
97
+ const { USE_COLOR, COLORS } = index.requireOutput();
98
+ const dim = USE_COLOR ? COLORS.dim : "";
99
+ const reset = USE_COLOR ? COLORS.reset : "";
100
+ const bold = USE_COLOR ? COLORS.bold : "";
101
+ const stages = RUN_PIPELINE_STAGES.join(` ${dim}\u2192${reset} `);
102
+ process.stdout.write(`${bold}mgw:run${reset} #${issueNumber} ${dim}${stages}${reset}
103
+ `);
104
+ }
45
105
  await runAiCommand("run", issueNumber, opts);
46
106
  });
47
107
  program.command("init").description("Bootstrap repo for MGW (state, templates, labels)").action(async function() {
@@ -60,6 +120,20 @@ function requireMgw () {
60
120
  const opts = this.optsWithGlobals();
61
121
  await runAiCommand("next", "", opts);
62
122
  });
123
+ program.command("status [milestone]").description("Project status dashboard \u2014 milestone progress, issue pipeline stages, open PRs").option("--board", "open GitHub Projects board URL").option("--watch", "live-refresh mode \u2014 redraws dashboard every N seconds").option("--interval <seconds>", "refresh interval for --watch (default: 30)").action(async function(milestone) {
124
+ const opts = this.optsWithGlobals();
125
+ if (opts.watch && opts.json) {
126
+ error("Error: --watch and --json cannot be used together.");
127
+ process.exit(1);
128
+ }
129
+ const args = [
130
+ milestone || "",
131
+ opts.board ? "--board" : "",
132
+ opts.watch ? "--watch" : "",
133
+ opts.interval ? `--interval ${opts.interval}` : ""
134
+ ].filter(Boolean).join(" ");
135
+ await runAiCommand("status", args, opts);
136
+ });
63
137
  program.command("issue <number>").description("Triage issue against codebase").action(async function(number) {
64
138
  const opts = this.optsWithGlobals();
65
139
  await runAiCommand("issue", number, opts);
@@ -161,12 +235,15 @@ function requireMgw () {
161
235
  log(`sync complete: ${ok} up-to-date, ${archived} archived`);
162
236
  }
163
237
  });
164
- program.command("issues [filters...]").description("List open issues").option("--label <label>", "filter by label").option("--milestone <name>", "filter by milestone").option("--assignee <user>", "filter by assignee (default: @me)", "@me").option("--state <state>", "issue state: open, closed, all (default: open)", "open").action(async function() {
238
+ program.command("issues [filters...]").description("Browse open issues \u2014 interactive TUI in TTY, static table otherwise").option("--label <label>", "filter by label").option("--milestone <name>", "filter by milestone").option("--assignee <user>", 'filter by assignee ("all" = no filter, default: all)', "all").option("--state <state>", "issue state: open, closed, all (default: open)", "open").option("-s, --search <query>", "pre-populate fuzzy search input").option("--limit <n>", "max issues to load (default: 50)", "50").action(async function() {
165
239
  const opts = this.optsWithGlobals();
166
240
  const ghFilters = {
167
- assignee: opts.assignee || "@me",
168
- state: opts.state || "open"
241
+ state: opts.state || "open",
242
+ limit: parseInt(opts.limit, 10) || 50
169
243
  };
244
+ if (opts.assignee && opts.assignee !== "all") {
245
+ ghFilters.assignee = opts.assignee;
246
+ }
170
247
  if (opts.label) ghFilters.label = opts.label;
171
248
  if (opts.milestone) ghFilters.milestone = opts.milestone;
172
249
  let issues;
@@ -185,16 +262,23 @@ function requireMgw () {
185
262
  log("No issues found.");
186
263
  return;
187
264
  }
188
- const pad = (s, n) => String(s).padEnd(n);
189
- log(pad("#", 6) + pad("Title", 60) + pad("State", 10) + "Labels");
190
- log("-".repeat(90));
191
- for (const issue of issues) {
192
- const labels = (issue.labels || []).map((l) => l.name || l).join(", ");
193
- log(
194
- pad(issue.number, 6) + pad((issue.title || "").substring(0, 58), 60) + pad(issue.state || "", 10) + labels
195
- );
196
- }
197
- log("\n" + issues.length + " issue(s)");
265
+ await createIssuesBrowser({
266
+ issues,
267
+ onSelect: function(issue) {
268
+ log("\nSelected: #" + issue.number + " \u2014 " + issue.title);
269
+ log("Run: mgw issue " + issue.number);
270
+ process.exit(0);
271
+ },
272
+ onQuit: function() {
273
+ process.exit(0);
274
+ },
275
+ initialQuery: opts.search || "",
276
+ initialFilter: {
277
+ label: opts.label,
278
+ milestone: opts.milestone,
279
+ assignee: opts.assignee || "all"
280
+ }
281
+ });
198
282
  });
199
283
  program.command("link <ref-a> <ref-b>").description("Cross-reference issues/PRs/branches").option("--quiet", "no GitHub comments").action(async function(refA, refB) {
200
284
  const opts = this.optsWithGlobals();
@@ -286,6 +370,6 @@ function requireMgw () {
286
370
  }
287
371
 
288
372
  var mgwExports = requireMgw();
289
- var mgw = /*@__PURE__*/claude.getDefaultExportFromCjs(mgwExports);
373
+ var mgw = /*@__PURE__*/index.getDefaultExportFromCjs(mgwExports);
290
374
 
291
375
  module.exports = mgw;