@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.
- package/README.md +20 -9
- package/commands/board.md +75 -0
- package/commands/milestone.md +138 -15
- package/commands/project.md +55 -1651
- package/commands/run.md +285 -11
- package/commands/sync.md +332 -1
- package/dist/bin/mgw.cjs +2 -2
- package/dist/{claude-Vp9qvImH.cjs → claude-Dk1oVsaG.cjs} +156 -0
- package/dist/lib/index.cjs +237 -12
- package/package.json +1 -1
package/dist/lib/index.cjs
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var claude = require('../claude-
|
|
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
|
|
10
|
-
var
|
|
9
|
+
var gsdAdapter;
|
|
10
|
+
var hasRequiredGsdAdapter;
|
|
11
11
|
|
|
12
|
-
function
|
|
13
|
-
if (
|
|
14
|
-
|
|
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(
|
|
20
|
-
|
|
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
|
-
|
|
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});
|