@snipcodeit/mgw 0.1.3 → 0.2.0

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.
@@ -0,0 +1,142 @@
1
+ #compdef mgw
2
+ # mgw zsh completion script
3
+ # Place in a directory on your $fpath (e.g. /usr/local/share/zsh/site-functions/_mgw)
4
+ # or source directly: source completions/mgw.zsh
5
+ # Generated by bin/generate-completions.cjs
6
+
7
+ _mgw() {
8
+ local context state state_descr line
9
+ typeset -A opt_args
10
+
11
+ local -a global_flags
12
+ global_flags=(
13
+ '--dry-run[show what would happen without executing]'
14
+ '--json[output structured JSON]'
15
+ '(-v --verbose)'{-v,--verbose}'[show API calls and file writes]'
16
+ '--debug[full payloads and timings]'
17
+ '--model[Claude model override]:model:(claude-opus-4-5 claude-sonnet-4-5 claude-haiku-4-5)'
18
+ )
19
+
20
+ _arguments -C \
21
+ "${global_flags[@]}" \
22
+ '(-h --help)'{-h,--help}'[display help]' \
23
+ '(-V --version)'{-V,--version}'[output the version number]' \
24
+ '1: :_mgw_subcommands' \
25
+ '*:: :->subcommand_args' \
26
+ && return 0
27
+
28
+ case "$state" in
29
+ subcommand_args)
30
+ case "$words[1]" in
31
+ run)
32
+ _arguments \
33
+ "${global_flags[@]}" \
34
+ '--quiet[buffer output, show summary at end]' \
35
+ '--auto[phase chaining: discuss -> plan -> execute]' \
36
+ '1:issue-number:_mgw_issue_numbers' \
37
+ && return 0
38
+ ;;
39
+ init)
40
+ _arguments "${global_flags[@]}" && return 0
41
+ ;;
42
+ project)
43
+ _arguments "${global_flags[@]}" && return 0
44
+ ;;
45
+ milestone)
46
+ _arguments \
47
+ "${global_flags[@]}" \
48
+ '--interactive[pause between issues for review]' \
49
+ '1::milestone-number:' \
50
+ && return 0
51
+ ;;
52
+ next)
53
+ _arguments "${global_flags[@]}" && return 0
54
+ ;;
55
+ issue)
56
+ _arguments \
57
+ "${global_flags[@]}" \
58
+ '1:issue-number:_mgw_issue_numbers' \
59
+ && return 0
60
+ ;;
61
+ update)
62
+ _arguments \
63
+ "${global_flags[@]}" \
64
+ '1:issue-number:_mgw_issue_numbers' \
65
+ '2::message:' \
66
+ && return 0
67
+ ;;
68
+ pr)
69
+ _arguments \
70
+ "${global_flags[@]}" \
71
+ '--base[custom base branch]:branch:_git_branch_names' \
72
+ '1::issue-number:_mgw_issue_numbers' \
73
+ && return 0
74
+ ;;
75
+ sync)
76
+ _arguments "${global_flags[@]}" && return 0
77
+ ;;
78
+ issues)
79
+ _arguments \
80
+ "${global_flags[@]}" \
81
+ '--label[filter by label]:label:' \
82
+ '--milestone[filter by milestone]:milestone:' \
83
+ '--assignee[filter by assignee]:assignee:(all @me)' \
84
+ '--state[issue state]:state:(open closed all)' \
85
+ '(-s --search)'{-s,--search}'[pre-populate fuzzy search input]:query:' \
86
+ '--limit[max issues to load]:number:(10 25 50 100)' \
87
+ && return 0
88
+ ;;
89
+ link)
90
+ _arguments \
91
+ "${global_flags[@]}" \
92
+ '--quiet[no GitHub comments]' \
93
+ '1:ref-a:' \
94
+ '2:ref-b:' \
95
+ && return 0
96
+ ;;
97
+ help)
98
+ return 0
99
+ ;;
100
+ esac
101
+ ;;
102
+ esac
103
+ }
104
+
105
+ _mgw_subcommands() {
106
+ local -a subcommands
107
+ subcommands=(
108
+ 'run:Run the full pipeline for an issue'
109
+ 'init:Bootstrap repo for MGW (state, templates, labels)'
110
+ 'project:Initialize project from template (milestones, issues, ROADMAP)'
111
+ 'milestone:Execute milestone issues in dependency order'
112
+ 'next:Show next unblocked issue'
113
+ 'issue:Triage issue against codebase'
114
+ 'update:Post status comment on issue'
115
+ 'pr:Create PR from GSD artifacts'
116
+ 'sync:Reconcile .mgw/ state with GitHub'
117
+ 'issues:Browse open issues'
118
+ 'link:Cross-reference issues/PRs/branches'
119
+ 'help:Show command reference'
120
+ )
121
+ _describe 'mgw subcommand' subcommands
122
+ }
123
+
124
+ _mgw_issue_numbers() {
125
+ # Attempt to complete issue numbers from active .mgw/ state
126
+ local -a active_issues
127
+ local active_dir=".mgw/active"
128
+ if [[ -d "$active_dir" ]]; then
129
+ for f in "$active_dir"/*.json; do
130
+ [[ -f "$f" ]] || continue
131
+ local num="${${f:t}%%[-_]*}"
132
+ [[ "$num" =~ ^[0-9]+$ ]] && active_issues+=("$num")
133
+ done
134
+ fi
135
+ if (( ${#active_issues[@]} > 0 )); then
136
+ _describe 'issue number' active_issues
137
+ else
138
+ _message 'issue number'
139
+ fi
140
+ }
141
+
142
+ _mgw "$@"
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.0";
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() {
@@ -161,12 +221,15 @@ function requireMgw () {
161
221
  log(`sync complete: ${ok} up-to-date, ${archived} archived`);
162
222
  }
163
223
  });
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() {
224
+ 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
225
  const opts = this.optsWithGlobals();
166
226
  const ghFilters = {
167
- assignee: opts.assignee || "@me",
168
- state: opts.state || "open"
227
+ state: opts.state || "open",
228
+ limit: parseInt(opts.limit, 10) || 50
169
229
  };
230
+ if (opts.assignee && opts.assignee !== "all") {
231
+ ghFilters.assignee = opts.assignee;
232
+ }
170
233
  if (opts.label) ghFilters.label = opts.label;
171
234
  if (opts.milestone) ghFilters.milestone = opts.milestone;
172
235
  let issues;
@@ -185,16 +248,23 @@ function requireMgw () {
185
248
  log("No issues found.");
186
249
  return;
187
250
  }
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)");
251
+ await createIssuesBrowser({
252
+ issues,
253
+ onSelect: function(issue) {
254
+ log("\nSelected: #" + issue.number + " \u2014 " + issue.title);
255
+ log("Run: mgw issue " + issue.number);
256
+ process.exit(0);
257
+ },
258
+ onQuit: function() {
259
+ process.exit(0);
260
+ },
261
+ initialQuery: opts.search || "",
262
+ initialFilter: {
263
+ label: opts.label,
264
+ milestone: opts.milestone,
265
+ assignee: opts.assignee || "all"
266
+ }
267
+ });
198
268
  });
199
269
  program.command("link <ref-a> <ref-b>").description("Cross-reference issues/PRs/branches").option("--quiet", "no GitHub comments").action(async function(refA, refB) {
200
270
  const opts = this.optsWithGlobals();
@@ -286,6 +356,6 @@ function requireMgw () {
286
356
  }
287
357
 
288
358
  var mgwExports = requireMgw();
289
- var mgw = /*@__PURE__*/claude.getDefaultExportFromCjs(mgwExports);
359
+ var mgw = /*@__PURE__*/index.getDefaultExportFromCjs(mgwExports);
290
360
 
291
361
  module.exports = mgw;