@programinglive/dev-workflow-mcp-server 1.0.9 → 1.1.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/CHANGELOG.md +43 -0
- package/README.md +2 -2
- package/commit-helpers.js +166 -0
- package/exec.js +4 -0
- package/git-helpers.js +152 -0
- package/index.js +45 -1300
- package/package.json +1 -1
- package/tests/handlers.test.js +460 -0
- package/tools/definitions.js +211 -0
- package/tools/handlers.js +739 -0
- package/utils.js +45 -0
- package/workflow-state.js +107 -0
package/utils.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const isWindows = process.platform === "win32";
|
|
2
|
+
|
|
3
|
+
export function shellEscape(value) {
|
|
4
|
+
const stringValue = String(value);
|
|
5
|
+
if (isWindows) {
|
|
6
|
+
// Use PowerShell-friendly single quotes, escape embedded single quotes by doubling
|
|
7
|
+
return `'${stringValue.replace(/'/g, "''")}'`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return `'${stringValue.replace(/'/g, "'\\''")}'`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function normalizeRequestArgs(rawArgs) {
|
|
14
|
+
if (rawArgs === undefined || rawArgs === null) {
|
|
15
|
+
return { args: {}, error: null };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (typeof rawArgs === "string") {
|
|
19
|
+
try {
|
|
20
|
+
const parsed = JSON.parse(rawArgs);
|
|
21
|
+
if (parsed && typeof parsed === "object") {
|
|
22
|
+
return { args: parsed, error: null };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
args: {},
|
|
27
|
+
error: "⚠️ Tool arguments must be a JSON object. Please provide key/value pairs.",
|
|
28
|
+
};
|
|
29
|
+
} catch (parseError) {
|
|
30
|
+
return {
|
|
31
|
+
args: {},
|
|
32
|
+
error: "⚠️ Unable to parse tool arguments. Please provide valid JSON-formatted data.",
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (typeof rawArgs === "object") {
|
|
38
|
+
return { args: rawArgs, error: null };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
args: {},
|
|
43
|
+
error: "⚠️ Unsupported tool arguments format. Expected a JSON object.",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
export class WorkflowState {
|
|
9
|
+
constructor(stateFilePath = path.join(__dirname, ".workflow-state.json")) {
|
|
10
|
+
this.stateFile = stateFilePath;
|
|
11
|
+
this.state = {
|
|
12
|
+
currentPhase: "idle",
|
|
13
|
+
taskDescription: "",
|
|
14
|
+
bugFixed: false,
|
|
15
|
+
testsCreated: false,
|
|
16
|
+
testsPassed: false,
|
|
17
|
+
testsSkipped: false,
|
|
18
|
+
testsSkippedReason: "",
|
|
19
|
+
documentationCreated: false,
|
|
20
|
+
readyToCommit: false,
|
|
21
|
+
readyCheckCompleted: false,
|
|
22
|
+
released: false,
|
|
23
|
+
releaseCommand: "",
|
|
24
|
+
releaseNotes: "",
|
|
25
|
+
commitAndPushCompleted: false,
|
|
26
|
+
lastCommitMessage: "",
|
|
27
|
+
lastPushBranch: "",
|
|
28
|
+
history: [],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async load() {
|
|
33
|
+
try {
|
|
34
|
+
const data = await fs.readFile(this.stateFile, "utf-8");
|
|
35
|
+
const parsed = JSON.parse(data);
|
|
36
|
+
this.state = {
|
|
37
|
+
...this.state,
|
|
38
|
+
...parsed,
|
|
39
|
+
};
|
|
40
|
+
if (typeof this.state.testsCreated !== "boolean") {
|
|
41
|
+
this.state.testsCreated = false;
|
|
42
|
+
}
|
|
43
|
+
if (typeof this.state.testsSkipped !== "boolean") {
|
|
44
|
+
this.state.testsSkipped = false;
|
|
45
|
+
}
|
|
46
|
+
if (typeof this.state.testsSkippedReason !== "string") {
|
|
47
|
+
this.state.testsSkippedReason = "";
|
|
48
|
+
}
|
|
49
|
+
if (typeof this.state.readyCheckCompleted !== "boolean") {
|
|
50
|
+
this.state.readyCheckCompleted = false;
|
|
51
|
+
}
|
|
52
|
+
if (typeof this.state.released !== "boolean") {
|
|
53
|
+
this.state.released = false;
|
|
54
|
+
}
|
|
55
|
+
if (typeof this.state.commitAndPushCompleted !== "boolean") {
|
|
56
|
+
this.state.commitAndPushCompleted = false;
|
|
57
|
+
}
|
|
58
|
+
if (typeof this.state.releaseCommand !== "string") {
|
|
59
|
+
this.state.releaseCommand = "";
|
|
60
|
+
}
|
|
61
|
+
if (typeof this.state.releaseNotes !== "string") {
|
|
62
|
+
this.state.releaseNotes = "";
|
|
63
|
+
}
|
|
64
|
+
if (typeof this.state.lastCommitMessage !== "string") {
|
|
65
|
+
this.state.lastCommitMessage = "";
|
|
66
|
+
}
|
|
67
|
+
if (typeof this.state.lastPushBranch !== "string") {
|
|
68
|
+
this.state.lastPushBranch = "";
|
|
69
|
+
}
|
|
70
|
+
} catch (error) {
|
|
71
|
+
// File doesn't exist yet, use default state
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async save() {
|
|
76
|
+
await fs.writeFile(this.stateFile, JSON.stringify(this.state, null, 2));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
reset() {
|
|
80
|
+
this.state = {
|
|
81
|
+
currentPhase: "idle",
|
|
82
|
+
taskDescription: "",
|
|
83
|
+
bugFixed: false,
|
|
84
|
+
testsCreated: false,
|
|
85
|
+
testsPassed: false,
|
|
86
|
+
testsSkipped: false,
|
|
87
|
+
testsSkippedReason: "",
|
|
88
|
+
documentationCreated: false,
|
|
89
|
+
readyToCommit: false,
|
|
90
|
+
readyCheckCompleted: false,
|
|
91
|
+
released: false,
|
|
92
|
+
releaseCommand: "",
|
|
93
|
+
releaseNotes: "",
|
|
94
|
+
commitAndPushCompleted: false,
|
|
95
|
+
lastCommitMessage: "",
|
|
96
|
+
lastPushBranch: "",
|
|
97
|
+
history: this.state.history,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
addToHistory(entry) {
|
|
102
|
+
this.state.history.push({
|
|
103
|
+
...entry,
|
|
104
|
+
timestamp: new Date().toISOString(),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|