@snipcodeit/mgw 0.2.1 → 0.3.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.
- package/README.md +55 -5
- package/commands/board/configure.md +205 -0
- package/commands/board/create.md +496 -0
- package/commands/board/show.md +221 -0
- package/commands/board/sync.md +417 -0
- package/commands/board/views.md +230 -0
- package/commands/board.md +23 -1543
- package/commands/review.md +222 -42
- package/commands/run/execute.md +675 -0
- package/commands/run/pr-create.md +282 -0
- package/commands/run/triage.md +510 -0
- package/commands/run/worktree.md +54 -0
- package/commands/run.md +23 -1497
- package/commands/workflows/gsd.md +1 -13
- package/dist/bin/mgw.cjs +95 -6
- package/dist/{index-CXfe9U4l.cjs → index-s7v-ifd0.cjs} +670 -51
- package/dist/lib/index.cjs +185 -142
- package/package.json +5 -2
|
@@ -364,24 +364,12 @@ and codebase to classify, then MGW presents the result and offers follow-up acti
|
|
|
364
364
|
- **NEVER** let MGW read application source code directly — spawn an analysis agent
|
|
365
365
|
- **NEVER** omit `subagent_type` from a Task() call — always specify the agent type
|
|
366
366
|
|
|
367
|
-
##
|
|
368
|
-
|
|
369
|
-
| Pattern | Referenced By |
|
|
370
|
-
|---------|-------------|
|
|
371
|
-
| Standard spawn template | run.md, issue.md, pr.md, ask.md, review.md |
|
|
372
|
-
| Comment classification | run.md (pre-flight), review.md (standalone) |
|
|
373
|
-
| Quick pipeline | run.md |
|
|
374
|
-
| Milestone pipeline | run.md, milestone.md |
|
|
375
|
-
| Question classification | ask.md |
|
|
376
|
-
| Model resolution | run.md |
|
|
377
|
-
TB|## PR Review Pattern
|
|
367
|
+
## PR Review Pattern
|
|
378
368
|
|
|
379
369
|
MGW:review has two modes:
|
|
380
370
|
1. **Issue Comment Review** (default) — Classifies new comments on an issue since triage
|
|
381
371
|
2. **PR Deep Review** (with --pr flag or PR URL) — Comprehensive senior engineer review
|
|
382
372
|
|
|
383
|
-
The PR Deep Review pattern below is for Mode 2. This is problem-solving orchestration
|
|
384
|
-
|
|
385
373
|
Used by `/mgw:review` for deep PR analysis. This is problem-solving orchestration
|
|
386
374
|
(not execution orchestration) — the reviewer has high autonomy to analyze, question
|
|
387
375
|
assumptions, and provide architectural guidance.
|
package/dist/bin/mgw.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var index = require('../index-
|
|
4
|
+
var index = require('../index-s7v-ifd0.cjs');
|
|
5
5
|
var require$$0 = require('commander');
|
|
6
6
|
var require$$1 = require('path');
|
|
7
7
|
var require$$0$2 = require('fs');
|
|
@@ -10,8 +10,8 @@ require('events');
|
|
|
10
10
|
|
|
11
11
|
var mgw$1 = {};
|
|
12
12
|
|
|
13
|
-
var version = "0.
|
|
14
|
-
var require$$
|
|
13
|
+
var version = "0.3.0";
|
|
14
|
+
var require$$11 = {
|
|
15
15
|
version: version};
|
|
16
16
|
|
|
17
17
|
var hasRequiredMgw;
|
|
@@ -29,7 +29,8 @@ function requireMgw () {
|
|
|
29
29
|
const { getIssue, listIssues } = index.requireGithub();
|
|
30
30
|
const { createIssuesBrowser } = index.requireTui();
|
|
31
31
|
const { createSpinner } = index.requireSpinner();
|
|
32
|
-
const
|
|
32
|
+
const { startTimer } = index.requireLogger();
|
|
33
|
+
const pkg = require$$11;
|
|
33
34
|
const program = new Command();
|
|
34
35
|
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
36
|
const STAGE_LABELS = {
|
|
@@ -46,6 +47,11 @@ function requireMgw () {
|
|
|
46
47
|
assertClaudeAvailable();
|
|
47
48
|
const cmdFile = path.join(getCommandsDir(), `${commandName}.md`);
|
|
48
49
|
const stageLabel = STAGE_LABELS[commandName] || commandName;
|
|
50
|
+
const issueMatch = String(userPrompt).match(/^\d+/);
|
|
51
|
+
const timer = startTimer({
|
|
52
|
+
command: commandName,
|
|
53
|
+
issue: issueMatch ? parseInt(issueMatch[0], 10) : void 0
|
|
54
|
+
});
|
|
49
55
|
if (opts.quiet) {
|
|
50
56
|
const spinner = createSpinner(`mgw:${stageLabel}`);
|
|
51
57
|
spinner.start();
|
|
@@ -59,12 +65,15 @@ function requireMgw () {
|
|
|
59
65
|
});
|
|
60
66
|
} catch (err) {
|
|
61
67
|
spinner.fail(`${stageLabel} failed`);
|
|
68
|
+
timer.finish("error", err.message);
|
|
62
69
|
throw err;
|
|
63
70
|
}
|
|
64
71
|
if (result.exitCode === 0) {
|
|
65
72
|
spinner.succeed(`${stageLabel} complete`);
|
|
73
|
+
timer.finish("ok");
|
|
66
74
|
} else {
|
|
67
75
|
spinner.fail(`${stageLabel} failed (exit ${result.exitCode})`);
|
|
76
|
+
timer.finish("error", `exit ${result.exitCode}`);
|
|
68
77
|
}
|
|
69
78
|
if (result.output) {
|
|
70
79
|
process.stdout.write(result.output);
|
|
@@ -81,6 +90,7 @@ function requireMgw () {
|
|
|
81
90
|
dryRun: opts.dryRun,
|
|
82
91
|
json: opts.json
|
|
83
92
|
});
|
|
93
|
+
timer.finish(result.exitCode === 0 ? "ok" : "error", result.exitCode !== 0 ? `exit ${result.exitCode}` : void 0);
|
|
84
94
|
process.exitCode = result.exitCode;
|
|
85
95
|
}
|
|
86
96
|
}
|
|
@@ -150,6 +160,7 @@ function requireMgw () {
|
|
|
150
160
|
});
|
|
151
161
|
program.command("sync").description("Reconcile .mgw/ state with GitHub").action(async function() {
|
|
152
162
|
const opts = this.optsWithGlobals();
|
|
163
|
+
const syncTimer = startTimer({ command: "sync" });
|
|
153
164
|
const activeDir = getActiveDir();
|
|
154
165
|
if (!fs.existsSync(activeDir)) {
|
|
155
166
|
if (opts.json) {
|
|
@@ -192,7 +203,7 @@ function requireMgw () {
|
|
|
192
203
|
}
|
|
193
204
|
let ghIssue;
|
|
194
205
|
try {
|
|
195
|
-
ghIssue = getIssue(number);
|
|
206
|
+
ghIssue = await getIssue(number);
|
|
196
207
|
} catch (err) {
|
|
197
208
|
error(`Failed to fetch issue #${number} from GitHub: ${err.message}`);
|
|
198
209
|
results.push({ number, file, status: "error", error: err.message });
|
|
@@ -234,6 +245,7 @@ function requireMgw () {
|
|
|
234
245
|
const ok = results.filter((r) => r.status === "ok").length;
|
|
235
246
|
log(`sync complete: ${ok} up-to-date, ${archived} archived`);
|
|
236
247
|
}
|
|
248
|
+
syncTimer.finish("ok");
|
|
237
249
|
});
|
|
238
250
|
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() {
|
|
239
251
|
const opts = this.optsWithGlobals();
|
|
@@ -248,7 +260,7 @@ function requireMgw () {
|
|
|
248
260
|
if (opts.milestone) ghFilters.milestone = opts.milestone;
|
|
249
261
|
let issues;
|
|
250
262
|
try {
|
|
251
|
-
issues = listIssues(ghFilters);
|
|
263
|
+
issues = await listIssues(ghFilters);
|
|
252
264
|
} catch (err) {
|
|
253
265
|
error("Failed to list issues: " + err.message);
|
|
254
266
|
process.exitCode = 1;
|
|
@@ -343,6 +355,83 @@ function requireMgw () {
|
|
|
343
355
|
log("Linked: " + refA + " <-> " + refB);
|
|
344
356
|
}
|
|
345
357
|
});
|
|
358
|
+
program.command("log").description("Query execution logs").option("--since <period>", "time period: 1d, 7d, 30d, or ISO date").option("--issue <number>", "filter by issue number").option("--command <name>", "filter by command name").option("--limit <n>", "max entries (default: 50)", "50").option("--metrics", "show aggregated metrics instead of log entries").action(function() {
|
|
359
|
+
const opts = this.optsWithGlobals();
|
|
360
|
+
const { readLogs, aggregateMetrics } = index.requireLogger();
|
|
361
|
+
const logOpts = {
|
|
362
|
+
since: opts.since,
|
|
363
|
+
issue: opts.issue ? parseInt(opts.issue, 10) : void 0,
|
|
364
|
+
command: opts.command,
|
|
365
|
+
limit: opts.metrics ? void 0 : parseInt(opts.limit, 10) || 50
|
|
366
|
+
};
|
|
367
|
+
const entries = readLogs(logOpts);
|
|
368
|
+
if (opts.metrics) {
|
|
369
|
+
const metrics = aggregateMetrics(entries);
|
|
370
|
+
if (opts.json) {
|
|
371
|
+
log(formatJson(metrics));
|
|
372
|
+
} else {
|
|
373
|
+
log(`Total invocations: ${metrics.total}`);
|
|
374
|
+
log(`Avg duration: ${metrics.avgDuration}ms`);
|
|
375
|
+
log(`Failure rate: ${metrics.failureRate}%`);
|
|
376
|
+
log("");
|
|
377
|
+
log("By command:");
|
|
378
|
+
for (const [cmd, stats] of Object.entries(metrics.byCommand)) {
|
|
379
|
+
log(` ${cmd}: ${stats.count} calls, ${stats.errors} errors, avg ${stats.avgDuration}ms`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
if (entries.length === 0) {
|
|
385
|
+
log("No log entries found.");
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (opts.json) {
|
|
389
|
+
log(formatJson(entries));
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
for (const e of entries) {
|
|
393
|
+
const ts = e.timestamp ? e.timestamp.slice(0, 19).replace("T", " ") : "?";
|
|
394
|
+
const issue = e.issue ? `#${e.issue}` : "";
|
|
395
|
+
const dur = typeof e.duration_ms === "number" ? `${e.duration_ms}ms` : "";
|
|
396
|
+
const status = e.status === "error" ? `ERR: ${e.error || "unknown"}` : e.status;
|
|
397
|
+
log(`${ts} ${(e.command || "").padEnd(12)} ${issue.padEnd(6)} ${dur.padEnd(8)} ${status}`);
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
program.command("metrics").description("Show execution metrics \u2014 success rates, durations, command usage").option("--since <period>", "time period: 1d, 7d, 30d, or ISO date (default: 7d)", "7d").option("--issue <number>", "filter by issue number").option("--command <name>", "filter by command name").action(function() {
|
|
401
|
+
const opts = this.optsWithGlobals();
|
|
402
|
+
const { readLogs, aggregateMetrics } = index.requireLogger();
|
|
403
|
+
const { USE_COLOR, COLORS } = index.requireOutput();
|
|
404
|
+
const logOpts = {
|
|
405
|
+
since: opts.since,
|
|
406
|
+
issue: opts.issue ? parseInt(opts.issue, 10) : void 0,
|
|
407
|
+
command: opts.command
|
|
408
|
+
};
|
|
409
|
+
const entries = readLogs(logOpts);
|
|
410
|
+
const metrics = aggregateMetrics(entries);
|
|
411
|
+
if (opts.json) {
|
|
412
|
+
log(formatJson(metrics));
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
if (metrics.total === 0) {
|
|
416
|
+
log("No log entries found for the given period.");
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const dim = USE_COLOR ? COLORS.dim : "";
|
|
420
|
+
const bold = USE_COLOR ? COLORS.bold : "";
|
|
421
|
+
const reset = USE_COLOR ? COLORS.reset : "";
|
|
422
|
+
log(`${bold}Execution Metrics${reset} ${dim}(${opts.since})${reset}`);
|
|
423
|
+
log("");
|
|
424
|
+
log(` Total invocations: ${metrics.total}`);
|
|
425
|
+
log(` Avg duration: ${metrics.avgDuration}ms`);
|
|
426
|
+
log(` Failure rate: ${metrics.failureRate}%`);
|
|
427
|
+
log("");
|
|
428
|
+
log(`${bold}By Command${reset}`);
|
|
429
|
+
log(`${" Command".padEnd(16)} ${"Calls".padEnd(8)} ${"Errors".padEnd(8)} ${"Avg ms".padEnd(10)}`);
|
|
430
|
+
log(` ${dim}${"\u2500".repeat(38)}${reset}`);
|
|
431
|
+
for (const [cmd, stats] of Object.entries(metrics.byCommand)) {
|
|
432
|
+
log(` ${cmd.padEnd(14)} ${String(stats.count).padEnd(8)} ${String(stats.errors).padEnd(8)} ${String(stats.avgDuration).padEnd(10)}`);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
346
435
|
program.command("help").description("Show command reference").action(function() {
|
|
347
436
|
const helpMdPath = path.join(getCommandsDir(), "help.md");
|
|
348
437
|
let helpText;
|