@snipcodeit/mgw 0.1.1 → 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,23 +1,29 @@
1
1
  'use strict';
2
2
 
3
- var claude = require('../claude-Vp9qvImH.cjs');
3
+ var claude = require('../claude-Dk1oVsaG.cjs');
4
4
  var require$$0 = require('child_process');
5
5
  var require$$1 = require('path');
6
6
  var require$$2 = require('os');
7
7
  var require$$0$1 = require('fs');
8
8
 
9
- var gsd;
10
- var hasRequiredGsd;
9
+ var gsdAdapter;
10
+ var hasRequiredGsdAdapter;
11
11
 
12
- function requireGsd () {
13
- if (hasRequiredGsd) return gsd;
14
- hasRequiredGsd = 1;
12
+ function requireGsdAdapter () {
13
+ if (hasRequiredGsdAdapter) return gsdAdapter;
14
+ hasRequiredGsdAdapter = 1;
15
15
  const { execSync } = require$$0;
16
16
  const path = require$$1;
17
17
  const os = require$$2;
18
+ const fs = require$$0$1;
18
19
  function getGsdToolsPath() {
19
- const standard = path.join(os.homedir(), ".claude", "get-shit-done", "bin", "gsd-tools.cjs");
20
- const fs = require$$0$1;
20
+ const standard = path.join(
21
+ os.homedir(),
22
+ ".claude",
23
+ "get-shit-done",
24
+ "bin",
25
+ "gsd-tools.cjs"
26
+ );
21
27
  if (fs.existsSync(standard)) {
22
28
  return standard;
23
29
  }
@@ -50,10 +56,109 @@ Ensure the get-shit-done framework is installed at ~/.claude/get-shit-done/`
50
56
  return raw;
51
57
  }
52
58
  }
53
- gsd = {
59
+ function getTimestamp() {
60
+ try {
61
+ const result = invokeGsdTool("current-timestamp", ["--raw"]);
62
+ return typeof result === "string" ? result : (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
63
+ } catch {
64
+ return (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
65
+ }
66
+ }
67
+ function generateSlug(title) {
68
+ const result = invokeGsdTool("generate-slug", [title]);
69
+ return typeof result === "string" ? result : String(result);
70
+ }
71
+ function resolveModel(agentType) {
72
+ const result = invokeGsdTool("resolve-model", [agentType, "--raw"]);
73
+ return typeof result === "string" ? result : String(result);
74
+ }
75
+ function historyDigest() {
76
+ return invokeGsdTool("history-digest", ["--raw"]);
77
+ }
78
+ function roadmapAnalyze() {
79
+ return invokeGsdTool("roadmap", ["analyze"]);
80
+ }
81
+ function selectGsdRoute(issue, projectState) {
82
+ const labels = Array.isArray(issue.labels) ? issue.labels : [];
83
+ const stage = typeof issue.pipeline_stage === "string" ? issue.pipeline_stage : "";
84
+ const labelStr = labels.map((l) => typeof l === "string" ? l : l.name || "").join(",").toLowerCase();
85
+ if (/gsd-route:quick|gsd:quick\b|(?:^|,)quick(?:,|$)/.test(labelStr)) {
86
+ return "quick";
87
+ }
88
+ if (/gsd-route:diagnose|needs-diagnosis/.test(labelStr)) {
89
+ return "diagnose";
90
+ }
91
+ if (stage === "diagnosing") {
92
+ return "diagnose";
93
+ }
94
+ if (stage === "executing") {
95
+ return "execute-only";
96
+ }
97
+ if (stage === "verifying") {
98
+ return "verify-only";
99
+ }
100
+ if (projectState && projectState.milestones) ;
101
+ return "plan-phase";
102
+ }
103
+ function getGsdState() {
104
+ const planningDir = path.join(process.cwd(), ".planning");
105
+ const stateMdPath = path.join(planningDir, "STATE.md");
106
+ const roadmapPath = path.join(planningDir, "ROADMAP.md");
107
+ if (!fs.existsSync(planningDir)) {
108
+ return null;
109
+ }
110
+ let activeMilestone = null;
111
+ let currentPhase = null;
112
+ let planCount = 0;
113
+ if (fs.existsSync(stateMdPath)) {
114
+ const stateContent = fs.readFileSync(stateMdPath, "utf-8");
115
+ const phaseMatch = stateContent.match(/(?:Current Phase|Phase)[:\s]+(\d+)/i);
116
+ if (phaseMatch) {
117
+ currentPhase = phaseMatch[1];
118
+ }
119
+ const planLines = stateContent.match(/\.planning\/phase-\d+/g);
120
+ if (planLines) {
121
+ planCount = planLines.length;
122
+ }
123
+ }
124
+ if (fs.existsSync(roadmapPath)) {
125
+ try {
126
+ const roadmapData = roadmapAnalyze();
127
+ if (roadmapData && typeof roadmapData === "object") {
128
+ activeMilestone = roadmapData.milestone || roadmapData.activeMilestone || null;
129
+ if (!currentPhase && roadmapData.currentPhase) {
130
+ currentPhase = String(roadmapData.currentPhase);
131
+ }
132
+ if (!planCount && roadmapData.planCount) {
133
+ planCount = Number(roadmapData.planCount) || 0;
134
+ }
135
+ }
136
+ } catch {
137
+ }
138
+ }
139
+ return { activeMilestone, currentPhase, planCount };
140
+ }
141
+ gsdAdapter = {
54
142
  getGsdToolsPath,
55
- invokeGsdTool
143
+ invokeGsdTool,
144
+ getTimestamp,
145
+ generateSlug,
146
+ resolveModel,
147
+ historyDigest,
148
+ roadmapAnalyze,
149
+ selectGsdRoute,
150
+ getGsdState
56
151
  };
152
+ return gsdAdapter;
153
+ }
154
+
155
+ var gsd;
156
+ var hasRequiredGsd;
157
+
158
+ function requireGsd () {
159
+ if (hasRequiredGsd) return gsd;
160
+ hasRequiredGsd = 1;
161
+ gsd = requireGsdAdapter();
57
162
  return gsd;
58
163
  }
59
164
 
@@ -371,6 +476,124 @@ function requireTemplates () {
371
476
  return templates;
372
477
  }
373
478
 
479
+ var retry;
480
+ var hasRequiredRetry;
481
+
482
+ function requireRetry () {
483
+ if (hasRequiredRetry) return retry;
484
+ hasRequiredRetry = 1;
485
+ const MAX_RETRIES = 3;
486
+ const BACKOFF_BASE_MS = 5e3;
487
+ const BACKOFF_MAX_MS = 3e5;
488
+ const TRANSIENT_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
489
+ const TRANSIENT_MESSAGE_PATTERNS = [
490
+ "network timeout",
491
+ "econnreset",
492
+ "econnrefused",
493
+ "etimedout",
494
+ "socket hang up",
495
+ "worktree lock",
496
+ "model overload",
497
+ "rate limit",
498
+ "too many requests",
499
+ "service unavailable",
500
+ "bad gateway",
501
+ "gateway timeout"
502
+ ];
503
+ const NEEDS_INFO_MESSAGE_PATTERNS = [
504
+ "ambiguous",
505
+ "missing required field",
506
+ "contradictory requirements",
507
+ "issue body"
508
+ ];
509
+ function classifyFailure(error) {
510
+ if (!error || typeof error !== "object") {
511
+ return { class: "permanent", reason: "no error object provided" };
512
+ }
513
+ const status = error.status;
514
+ const message = (error.message || "").toLowerCase();
515
+ const code = (error.code || "").toLowerCase();
516
+ if (typeof status === "number") {
517
+ if (status === 429) {
518
+ return { class: "transient", reason: "rate limit (HTTP 429)" };
519
+ }
520
+ if (TRANSIENT_STATUS_CODES.has(status)) {
521
+ return { class: "transient", reason: `server error (HTTP ${status})` };
522
+ }
523
+ if (status === 403) {
524
+ return { class: "permanent", reason: "forbidden (HTTP 403 \u2014 non-rate-limit)" };
525
+ }
526
+ if (status >= 400 && status < 500) {
527
+ return { class: "permanent", reason: `client error (HTTP ${status})` };
528
+ }
529
+ }
530
+ if (code) {
531
+ const networkCodes = /* @__PURE__ */ new Set([
532
+ "econnreset",
533
+ "econnrefused",
534
+ "etimedout",
535
+ "enotfound",
536
+ "epipe"
537
+ ]);
538
+ if (networkCodes.has(code)) {
539
+ return { class: "transient", reason: `network error (${code.toUpperCase()})` };
540
+ }
541
+ if (code === "enoent") {
542
+ return { class: "permanent", reason: "file not found (ENOENT) \u2014 GSD tools may be missing" };
543
+ }
544
+ }
545
+ for (const pattern of TRANSIENT_MESSAGE_PATTERNS) {
546
+ if (message.includes(pattern)) {
547
+ return { class: "transient", reason: `transient condition detected: "${pattern}"` };
548
+ }
549
+ }
550
+ for (const pattern of NEEDS_INFO_MESSAGE_PATTERNS) {
551
+ if (message.includes(pattern)) {
552
+ return { class: "needs-info", reason: `issue requires clarification: "${pattern}"` };
553
+ }
554
+ }
555
+ return {
556
+ class: "permanent",
557
+ reason: "unknown error \u2014 classified as permanent to prevent runaway retries"
558
+ };
559
+ }
560
+ function canRetry(issueState) {
561
+ if (!issueState || typeof issueState !== "object") return false;
562
+ if (issueState.dead_letter === true) return false;
563
+ const count = typeof issueState.retry_count === "number" ? issueState.retry_count : 0;
564
+ return count < MAX_RETRIES;
565
+ }
566
+ function incrementRetry(issueState) {
567
+ const current = typeof issueState.retry_count === "number" ? issueState.retry_count : 0;
568
+ return Object.assign({}, issueState, { retry_count: current + 1 });
569
+ }
570
+ function resetRetryState(issueState) {
571
+ return Object.assign({}, issueState, {
572
+ retry_count: 0,
573
+ last_failure_class: null,
574
+ dead_letter: false
575
+ });
576
+ }
577
+ function getBackoffMs(retryCount) {
578
+ const count = Math.max(0, Math.floor(retryCount));
579
+ const base = Math.min(BACKOFF_MAX_MS, BACKOFF_BASE_MS * Math.pow(2, count));
580
+ return Math.floor(Math.random() * (base + 1));
581
+ }
582
+ retry = {
583
+ // Constants
584
+ MAX_RETRIES,
585
+ BACKOFF_BASE_MS,
586
+ BACKOFF_MAX_MS,
587
+ // Core functions
588
+ classifyFailure,
589
+ canRetry,
590
+ incrementRetry,
591
+ resetRetryState,
592
+ getBackoffMs
593
+ };
594
+ return retry;
595
+ }
596
+
374
597
  var lib;
375
598
  var hasRequiredLib;
376
599
 
@@ -381,9 +604,11 @@ function requireLib () {
381
604
  ...claude.requireState(),
382
605
  ...claude.requireGithub(),
383
606
  ...requireGsd(),
607
+ ...requireGsdAdapter(),
384
608
  ...requireTemplates(),
385
609
  ...claude.requireOutput(),
386
- ...claude.requireClaude()
610
+ ...claude.requireClaude(),
611
+ ...requireRetry()
387
612
  };
388
613
  return lib;
389
614
  }
@@ -392,4 +617,4 @@ var libExports = requireLib();
392
617
  var index = /*@__PURE__*/claude.getDefaultExportFromCjs(libExports);
393
618
 
394
619
  module.exports = index;
395
- 0&&(module.exports={getMgwDir,getActiveDir,getCompletedDir,loadProjectState,writeProjectState,loadActiveIssue,mergeProjectState,migrateProjectState,resolveActiveMilestoneIndex,getRepo,getIssue,listIssues,getMilestone,getRateLimit,closeMilestone,createRelease,createProject,addItemToProject,postMilestoneStartAnnouncement,getGsdToolsPath,invokeGsdTool,validate,getSchema,VALID_GSD_ROUTES,IS_TTY,IS_CI,USE_COLOR,COLORS,colorize,statusLine,log,error,verbose,debug,formatJson,assertClaudeAvailable,invokeClaude,getCommandsDir});
620
+ 0&&(module.exports={getMgwDir,getActiveDir,getCompletedDir,loadProjectState,writeProjectState,loadActiveIssue,mergeProjectState,migrateProjectState,resolveActiveMilestoneIndex,getRepo,getIssue,listIssues,getMilestone,getRateLimit,closeMilestone,createRelease,getProjectNodeId,findExistingBoard,getProjectFields,createProject,addItemToProject,postMilestoneStartAnnouncement,getGsdToolsPath,invokeGsdTool,getTimestamp,generateSlug,resolveModel,historyDigest,roadmapAnalyze,selectGsdRoute,getGsdState,validate,getSchema,VALID_GSD_ROUTES,IS_TTY,IS_CI,USE_COLOR,COLORS,colorize,statusLine,log,error,verbose,debug,formatJson,assertClaudeAvailable,invokeClaude,getCommandsDir,MAX_RETRIES,BACKOFF_BASE_MS,BACKOFF_MAX_MS,classifyFailure,canRetry,incrementRetry,resetRetryState,getBackoffMs});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snipcodeit/mgw",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "GitHub-native issue-to-PR automation for Claude Code, powered by Get Shit Done",
5
5
  "bin": {
6
6
  "mgw": "./dist/bin/mgw.cjs"