purple-ai 0.0.13 → 0.0.14
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/mcp-server/dist/bundle.js +161 -272
- package/package.json +1 -1
|
@@ -20646,173 +20646,139 @@ var StdioServerTransport = class {
|
|
|
20646
20646
|
|
|
20647
20647
|
// dist/index.js
|
|
20648
20648
|
var PURPLE_STATUS_URL = "http://127.0.0.1:7685/status";
|
|
20649
|
-
var PURPLE_STANDARDS_COMPLETE_URL = "http://127.0.0.1:7685/standards-complete";
|
|
20650
|
-
var PURPLE_SET_FEATURE_FOLDER_URL = "http://127.0.0.1:7685/set-feature-folder";
|
|
20651
20649
|
var TOOLS = [
|
|
20652
20650
|
{
|
|
20653
|
-
name: "
|
|
20654
|
-
description: "Update
|
|
20651
|
+
name: "purple_status",
|
|
20652
|
+
description: "Update Purple CLI status bar and ticket tree. Use this unified tool for all progress reporting: setting phases, tracking tickets, updating agent status, and managing feature folders.",
|
|
20655
20653
|
inputSchema: {
|
|
20656
20654
|
type: "object",
|
|
20657
20655
|
properties: {
|
|
20656
|
+
// Feature folder (sets progress.json location - typically sent once at start)
|
|
20657
|
+
featureFolder: {
|
|
20658
|
+
type: "string",
|
|
20659
|
+
description: 'Path to feature folder containing progress.json (e.g., "purple/documentation/260113-my-feature")'
|
|
20660
|
+
},
|
|
20661
|
+
// Status bar fields
|
|
20658
20662
|
phase: {
|
|
20659
20663
|
type: "string",
|
|
20660
|
-
description: 'Current phase (e.g., "
|
|
20664
|
+
description: 'Current phase (e.g., "1 - Product Spec", "2 - Engineering", "3 - Implementation")'
|
|
20661
20665
|
},
|
|
20662
20666
|
agent: {
|
|
20663
20667
|
type: "string",
|
|
20664
20668
|
description: 'Active agent name (e.g., "orchestrator", "senior-engineer", "spec-writer")'
|
|
20665
20669
|
},
|
|
20666
|
-
currentTicket: {
|
|
20667
|
-
type: "number",
|
|
20668
|
-
description: "Current ticket number being worked on (1-indexed)"
|
|
20669
|
-
},
|
|
20670
|
-
totalTickets: {
|
|
20671
|
-
type: "number",
|
|
20672
|
-
description: "Total number of tickets in the implementation"
|
|
20673
|
-
},
|
|
20674
20670
|
mode: {
|
|
20675
20671
|
type: "string",
|
|
20676
20672
|
enum: ["plan", "execute", "review"],
|
|
20677
|
-
description: 'Current working mode: "plan" (analyzing
|
|
20678
|
-
},
|
|
20679
|
-
tool: {
|
|
20680
|
-
type: "string",
|
|
20681
|
-
description: 'Currently active tool being used (e.g., "Edit", "Grep", "Read", "Bash")'
|
|
20673
|
+
description: 'Current working mode: "plan" (analyzing), "execute" (writing code), "review" (verifying)'
|
|
20682
20674
|
},
|
|
20683
20675
|
activeFile: {
|
|
20684
20676
|
type: "string",
|
|
20685
20677
|
description: "File currently being worked on (e.g., src/components/Button.tsx)"
|
|
20686
|
-
}
|
|
20687
|
-
},
|
|
20688
|
-
additionalProperties: false
|
|
20689
|
-
}
|
|
20690
|
-
},
|
|
20691
|
-
{
|
|
20692
|
-
name: "purple_set_phase",
|
|
20693
|
-
description: "Quick helper to set just the current phase. Use this when transitioning between major workflow phases.",
|
|
20694
|
-
inputSchema: {
|
|
20695
|
-
type: "object",
|
|
20696
|
-
properties: {
|
|
20697
|
-
phase: {
|
|
20698
|
-
type: "string",
|
|
20699
|
-
description: 'Phase name (e.g., "0 - Validation", "1 - Product Spec", "2 - Engineering", "3 - Implementation", "4 - Review")'
|
|
20700
|
-
}
|
|
20701
|
-
},
|
|
20702
|
-
required: ["phase"],
|
|
20703
|
-
additionalProperties: false
|
|
20704
|
-
}
|
|
20705
|
-
},
|
|
20706
|
-
{
|
|
20707
|
-
name: "purple_report_progress",
|
|
20708
|
-
description: "Report ticket progress during implementation. Call this at the start of each ticket to update the progress indicator.",
|
|
20709
|
-
inputSchema: {
|
|
20710
|
-
type: "object",
|
|
20711
|
-
properties: {
|
|
20712
|
-
current: {
|
|
20713
|
-
type: "number",
|
|
20714
|
-
description: "Current ticket number (1-indexed)"
|
|
20715
20678
|
},
|
|
20716
|
-
|
|
20679
|
+
// Overall progress
|
|
20680
|
+
completedTickets: {
|
|
20717
20681
|
type: "number",
|
|
20718
|
-
description: "Total
|
|
20719
|
-
}
|
|
20720
|
-
},
|
|
20721
|
-
required: ["current", "total"],
|
|
20722
|
-
additionalProperties: false
|
|
20723
|
-
}
|
|
20724
|
-
},
|
|
20725
|
-
{
|
|
20726
|
-
name: "purple_ticket_status",
|
|
20727
|
-
description: "Update ticket progress with phase information. Use this to show progress like '5/12 tickets done' in the status bar. Call this whenever starting a new ticket or completing one.",
|
|
20728
|
-
inputSchema: {
|
|
20729
|
-
type: "object",
|
|
20730
|
-
properties: {
|
|
20731
|
-
phase: {
|
|
20732
|
-
type: "string",
|
|
20733
|
-
description: 'Current phase name (e.g., "Phase 3: Implementation", "Phase 4: Review")'
|
|
20682
|
+
description: "Total tickets completed so far"
|
|
20734
20683
|
},
|
|
20735
|
-
|
|
20684
|
+
totalTickets: {
|
|
20736
20685
|
type: "number",
|
|
20737
|
-
description: "
|
|
20686
|
+
description: "Total number of tickets in the feature"
|
|
20738
20687
|
},
|
|
20739
|
-
|
|
20740
|
-
|
|
20741
|
-
|
|
20688
|
+
// QA section fields
|
|
20689
|
+
qaActive: {
|
|
20690
|
+
type: "boolean",
|
|
20691
|
+
description: "Set true when starting QA, false when QA completes. When false, shows checkmark in panel."
|
|
20742
20692
|
},
|
|
20743
|
-
|
|
20744
|
-
type: "
|
|
20745
|
-
description:
|
|
20746
|
-
}
|
|
20747
|
-
},
|
|
20748
|
-
required: ["completed", "total"],
|
|
20749
|
-
additionalProperties: false
|
|
20750
|
-
}
|
|
20751
|
-
},
|
|
20752
|
-
{
|
|
20753
|
-
name: "purple_standards_complete",
|
|
20754
|
-
description: "Signal that standards creation/update is complete. Call this when the create-standards agent has finished writing all standards files. This triggers automatic upload of standards to the Purple database.",
|
|
20755
|
-
inputSchema: {
|
|
20756
|
-
type: "object",
|
|
20757
|
-
properties: {
|
|
20758
|
-
message: {
|
|
20759
|
-
type: "string",
|
|
20760
|
-
description: 'Optional completion message (e.g., "Created 12 standards files")'
|
|
20761
|
-
}
|
|
20762
|
-
},
|
|
20763
|
-
additionalProperties: false
|
|
20764
|
-
}
|
|
20765
|
-
},
|
|
20766
|
-
{
|
|
20767
|
-
name: "purple_set_feature_folder",
|
|
20768
|
-
description: "Set the active feature folder for progress tracking. Call this when starting work on a feature to enable real-time progress.json monitoring. The folder should be the feature documentation folder (e.g., 'purple/documentation/260113-my-feature').",
|
|
20769
|
-
inputSchema: {
|
|
20770
|
-
type: "object",
|
|
20771
|
-
properties: {
|
|
20772
|
-
folder: {
|
|
20773
|
-
type: "string",
|
|
20774
|
-
description: 'Absolute or relative path to the feature folder containing progress.json (e.g., "purple/documentation/260113-my-feature")'
|
|
20775
|
-
}
|
|
20776
|
-
},
|
|
20777
|
-
required: ["folder"],
|
|
20778
|
-
additionalProperties: false
|
|
20779
|
-
}
|
|
20780
|
-
},
|
|
20781
|
-
{
|
|
20782
|
-
name: "purple_progress_start_ticket",
|
|
20783
|
-
description: "Mark a ticket as in_progress and show it in the Purple progress panel. Call this when starting work on a ticket.",
|
|
20784
|
-
inputSchema: {
|
|
20785
|
-
type: "object",
|
|
20786
|
-
properties: {
|
|
20787
|
-
ticketId: {
|
|
20788
|
-
type: "string",
|
|
20789
|
-
description: 'The ticket ID (e.g., "FCB-003")'
|
|
20693
|
+
qaRunNumber: {
|
|
20694
|
+
type: "number",
|
|
20695
|
+
description: "Current QA run number (1, 2, 3...)"
|
|
20790
20696
|
},
|
|
20791
|
-
|
|
20697
|
+
qaCurrentTest: {
|
|
20792
20698
|
type: "string",
|
|
20793
|
-
description: '
|
|
20699
|
+
description: 'Status text (e.g., "Running unit tests" when active, "Passed" or "Failed" when complete)'
|
|
20794
20700
|
},
|
|
20795
|
-
|
|
20796
|
-
|
|
20797
|
-
|
|
20798
|
-
|
|
20799
|
-
|
|
20800
|
-
|
|
20801
|
-
|
|
20802
|
-
|
|
20803
|
-
|
|
20804
|
-
|
|
20805
|
-
|
|
20806
|
-
|
|
20807
|
-
|
|
20808
|
-
|
|
20809
|
-
|
|
20810
|
-
|
|
20811
|
-
|
|
20812
|
-
|
|
20701
|
+
// Ticket data (announce/update a specific ticket)
|
|
20702
|
+
ticket: {
|
|
20703
|
+
type: "object",
|
|
20704
|
+
description: "Full ticket data for announcing or updating a ticket",
|
|
20705
|
+
properties: {
|
|
20706
|
+
id: {
|
|
20707
|
+
type: "string",
|
|
20708
|
+
description: 'Ticket ID (e.g., "FCB-003")'
|
|
20709
|
+
},
|
|
20710
|
+
name: {
|
|
20711
|
+
type: "string",
|
|
20712
|
+
description: 'Ticket name (e.g., "Firebase authentication")'
|
|
20713
|
+
},
|
|
20714
|
+
description: {
|
|
20715
|
+
type: "string",
|
|
20716
|
+
description: "Detailed description of the ticket"
|
|
20717
|
+
},
|
|
20718
|
+
phase: {
|
|
20719
|
+
type: "string",
|
|
20720
|
+
description: 'Phase this ticket belongs to (e.g., "Phase 1: Setup")'
|
|
20721
|
+
},
|
|
20722
|
+
acceptance: {
|
|
20723
|
+
type: "array",
|
|
20724
|
+
items: { type: "string" },
|
|
20725
|
+
description: "List of acceptance criteria for the ticket"
|
|
20726
|
+
},
|
|
20727
|
+
status: {
|
|
20728
|
+
type: "object",
|
|
20729
|
+
description: "Ticket status and timing information",
|
|
20730
|
+
properties: {
|
|
20731
|
+
status: {
|
|
20732
|
+
type: "string",
|
|
20733
|
+
enum: ["todo", "in_progress", "completed", "failed"],
|
|
20734
|
+
description: "Current ticket status"
|
|
20735
|
+
},
|
|
20736
|
+
startedAt: {
|
|
20737
|
+
type: "string",
|
|
20738
|
+
description: "ISO timestamp when work started"
|
|
20739
|
+
},
|
|
20740
|
+
updatedAt: {
|
|
20741
|
+
type: "string",
|
|
20742
|
+
description: "ISO timestamp of last update"
|
|
20743
|
+
},
|
|
20744
|
+
exceptionDescription: {
|
|
20745
|
+
type: "string",
|
|
20746
|
+
description: "Description of any blocker or exception encountered"
|
|
20747
|
+
},
|
|
20748
|
+
completionSummary: {
|
|
20749
|
+
type: "string",
|
|
20750
|
+
description: "Summary of what was accomplished"
|
|
20751
|
+
}
|
|
20752
|
+
}
|
|
20753
|
+
},
|
|
20754
|
+
dependencies: {
|
|
20755
|
+
type: "array",
|
|
20756
|
+
description: "List of ticket dependencies",
|
|
20757
|
+
items: {
|
|
20758
|
+
type: "object",
|
|
20759
|
+
properties: {
|
|
20760
|
+
id: { type: "string", description: "Dependent ticket ID" },
|
|
20761
|
+
phase: { type: "string", description: "Phase of dependent ticket" }
|
|
20762
|
+
}
|
|
20763
|
+
}
|
|
20764
|
+
},
|
|
20765
|
+
estimatedEffort: {
|
|
20766
|
+
type: "object",
|
|
20767
|
+
description: "Effort estimates for the ticket",
|
|
20768
|
+
properties: {
|
|
20769
|
+
humanEffort: {
|
|
20770
|
+
type: "string",
|
|
20771
|
+
description: 'Estimated human effort (e.g., "30 minutes")'
|
|
20772
|
+
},
|
|
20773
|
+
purpleEffort: {
|
|
20774
|
+
type: "string",
|
|
20775
|
+
description: 'Estimated Purple/AI effort (e.g., "5 minutes")'
|
|
20776
|
+
}
|
|
20777
|
+
}
|
|
20778
|
+
}
|
|
20779
|
+
}
|
|
20813
20780
|
}
|
|
20814
20781
|
},
|
|
20815
|
-
required: ["ticketId"],
|
|
20816
20782
|
additionalProperties: false
|
|
20817
20783
|
}
|
|
20818
20784
|
}
|
|
@@ -20833,42 +20799,10 @@ async function sendStatusUpdate(payload) {
|
|
|
20833
20799
|
console.error("Failed to send status update (Purple may not be active):", error2);
|
|
20834
20800
|
}
|
|
20835
20801
|
}
|
|
20836
|
-
async function sendStandardsComplete(payload) {
|
|
20837
|
-
try {
|
|
20838
|
-
const response = await fetch(PURPLE_STANDARDS_COMPLETE_URL, {
|
|
20839
|
-
method: "POST",
|
|
20840
|
-
headers: {
|
|
20841
|
-
"Content-Type": "application/json"
|
|
20842
|
-
},
|
|
20843
|
-
body: JSON.stringify(payload)
|
|
20844
|
-
});
|
|
20845
|
-
if (!response.ok) {
|
|
20846
|
-
console.error(`Standards complete signal failed with HTTP ${response.status}: ${response.statusText}`);
|
|
20847
|
-
}
|
|
20848
|
-
} catch (error2) {
|
|
20849
|
-
console.error("Failed to send standards complete signal (Purple may not be active):", error2);
|
|
20850
|
-
}
|
|
20851
|
-
}
|
|
20852
|
-
async function sendSetFeatureFolder(payload) {
|
|
20853
|
-
try {
|
|
20854
|
-
const response = await fetch(PURPLE_SET_FEATURE_FOLDER_URL, {
|
|
20855
|
-
method: "POST",
|
|
20856
|
-
headers: {
|
|
20857
|
-
"Content-Type": "application/json"
|
|
20858
|
-
},
|
|
20859
|
-
body: JSON.stringify(payload)
|
|
20860
|
-
});
|
|
20861
|
-
if (!response.ok) {
|
|
20862
|
-
console.error(`Set feature folder failed with HTTP ${response.status}: ${response.statusText}`);
|
|
20863
|
-
}
|
|
20864
|
-
} catch (error2) {
|
|
20865
|
-
console.error("Failed to set feature folder (Purple may not be active):", error2);
|
|
20866
|
-
}
|
|
20867
|
-
}
|
|
20868
20802
|
async function main() {
|
|
20869
20803
|
const server = new Server({
|
|
20870
20804
|
name: "purple-status",
|
|
20871
|
-
version: "
|
|
20805
|
+
version: "2.0.0"
|
|
20872
20806
|
}, {
|
|
20873
20807
|
capabilities: {
|
|
20874
20808
|
tools: {}
|
|
@@ -20881,120 +20815,75 @@ async function main() {
|
|
|
20881
20815
|
});
|
|
20882
20816
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
20883
20817
|
const { name, arguments: args } = request.params;
|
|
20884
|
-
|
|
20885
|
-
|
|
20886
|
-
|
|
20887
|
-
|
|
20888
|
-
|
|
20889
|
-
|
|
20890
|
-
|
|
20891
|
-
|
|
20892
|
-
|
|
20893
|
-
|
|
20894
|
-
|
|
20895
|
-
|
|
20896
|
-
|
|
20897
|
-
|
|
20898
|
-
|
|
20899
|
-
|
|
20900
|
-
|
|
20901
|
-
|
|
20902
|
-
|
|
20903
|
-
|
|
20904
|
-
|
|
20905
|
-
|
|
20906
|
-
|
|
20907
|
-
|
|
20908
|
-
|
|
20909
|
-
|
|
20910
|
-
|
|
20911
|
-
|
|
20912
|
-
|
|
20913
|
-
|
|
20914
|
-
|
|
20915
|
-
|
|
20916
|
-
|
|
20917
|
-
|
|
20918
|
-
|
|
20919
|
-
|
|
20920
|
-
|
|
20921
|
-
|
|
20922
|
-
|
|
20923
|
-
|
|
20924
|
-
|
|
20925
|
-
|
|
20926
|
-
|
|
20927
|
-
|
|
20928
|
-
|
|
20929
|
-
}
|
|
20930
|
-
case "purple_standards_complete": {
|
|
20931
|
-
const typedArgs = args;
|
|
20932
|
-
await sendStandardsComplete({ message: typedArgs.message });
|
|
20933
|
-
return {
|
|
20934
|
-
content: [
|
|
20935
|
-
{
|
|
20936
|
-
type: "text",
|
|
20937
|
-
text: "Standards upload triggered"
|
|
20938
|
-
}
|
|
20939
|
-
]
|
|
20940
|
-
};
|
|
20941
|
-
}
|
|
20942
|
-
case "purple_set_feature_folder": {
|
|
20943
|
-
const typedArgs = args;
|
|
20944
|
-
await sendSetFeatureFolder({ folder: typedArgs.folder });
|
|
20945
|
-
return {
|
|
20946
|
-
content: [
|
|
20947
|
-
{
|
|
20948
|
-
type: "text",
|
|
20949
|
-
text: `Feature folder set to: ${typedArgs.folder}`
|
|
20950
|
-
}
|
|
20951
|
-
]
|
|
20952
|
-
};
|
|
20953
|
-
}
|
|
20954
|
-
case "purple_progress_start_ticket": {
|
|
20955
|
-
const typedArgs = args;
|
|
20956
|
-
payload = {
|
|
20957
|
-
tool: name,
|
|
20958
|
-
ticketId: typedArgs.ticketId,
|
|
20959
|
-
ticketName: typedArgs.ticketName || "",
|
|
20960
|
-
agent: typedArgs.agent || "senior-engineer",
|
|
20961
|
-
ticketAction: "start"
|
|
20962
|
-
};
|
|
20963
|
-
break;
|
|
20964
|
-
}
|
|
20965
|
-
case "purple_progress_complete_ticket": {
|
|
20966
|
-
const typedArgs = args;
|
|
20967
|
-
payload = {
|
|
20968
|
-
tool: name,
|
|
20969
|
-
ticketId: typedArgs.ticketId,
|
|
20970
|
-
ticketAction: "complete"
|
|
20971
|
-
};
|
|
20972
|
-
break;
|
|
20973
|
-
}
|
|
20974
|
-
default:
|
|
20975
|
-
return {
|
|
20976
|
-
content: [
|
|
20977
|
-
{
|
|
20978
|
-
type: "text",
|
|
20979
|
-
text: `Unknown tool: ${name}`
|
|
20980
|
-
}
|
|
20981
|
-
],
|
|
20982
|
-
isError: true
|
|
20983
|
-
};
|
|
20818
|
+
if (name !== "purple_status") {
|
|
20819
|
+
return {
|
|
20820
|
+
content: [
|
|
20821
|
+
{
|
|
20822
|
+
type: "text",
|
|
20823
|
+
text: `Unknown tool: ${name}. Use 'purple_status' for all status updates.`
|
|
20824
|
+
}
|
|
20825
|
+
],
|
|
20826
|
+
isError: true
|
|
20827
|
+
};
|
|
20828
|
+
}
|
|
20829
|
+
const typedArgs = args;
|
|
20830
|
+
const payload = {};
|
|
20831
|
+
if (typedArgs.featureFolder) {
|
|
20832
|
+
payload.featureFolder = typedArgs.featureFolder;
|
|
20833
|
+
}
|
|
20834
|
+
if (typedArgs.phase) {
|
|
20835
|
+
payload.phase = typedArgs.phase;
|
|
20836
|
+
}
|
|
20837
|
+
if (typedArgs.agent) {
|
|
20838
|
+
payload.agent = typedArgs.agent;
|
|
20839
|
+
}
|
|
20840
|
+
if (typedArgs.mode) {
|
|
20841
|
+
payload.mode = typedArgs.mode;
|
|
20842
|
+
}
|
|
20843
|
+
if (typedArgs.activeFile) {
|
|
20844
|
+
payload.activeFile = typedArgs.activeFile;
|
|
20845
|
+
}
|
|
20846
|
+
if (typedArgs.completedTickets !== void 0) {
|
|
20847
|
+
payload.completedTickets = typedArgs.completedTickets;
|
|
20848
|
+
}
|
|
20849
|
+
if (typedArgs.totalTickets !== void 0) {
|
|
20850
|
+
payload.totalTickets = typedArgs.totalTickets;
|
|
20851
|
+
}
|
|
20852
|
+
if (typedArgs.qaActive !== void 0) {
|
|
20853
|
+
payload.qaActive = typedArgs.qaActive;
|
|
20854
|
+
}
|
|
20855
|
+
if (typedArgs.qaRunNumber !== void 0) {
|
|
20856
|
+
payload.qaRunNumber = typedArgs.qaRunNumber;
|
|
20857
|
+
}
|
|
20858
|
+
if (typedArgs.qaCurrentTest) {
|
|
20859
|
+
payload.qaCurrentTest = typedArgs.qaCurrentTest;
|
|
20860
|
+
}
|
|
20861
|
+
if (typedArgs.ticket) {
|
|
20862
|
+
payload.ticket = typedArgs.ticket;
|
|
20984
20863
|
}
|
|
20985
20864
|
await sendStatusUpdate(payload);
|
|
20865
|
+
let responseText = "Status updated";
|
|
20866
|
+
if (typedArgs.ticket?.id && typedArgs.ticket?.status?.status) {
|
|
20867
|
+
responseText = `Ticket ${typedArgs.ticket.id}: ${typedArgs.ticket.status.status}`;
|
|
20868
|
+
} else if (typedArgs.ticket?.id) {
|
|
20869
|
+
responseText = `Ticket ${typedArgs.ticket.id} updated`;
|
|
20870
|
+
} else if (typedArgs.featureFolder) {
|
|
20871
|
+
responseText = `Feature folder set to: ${typedArgs.featureFolder}`;
|
|
20872
|
+
} else if (typedArgs.phase) {
|
|
20873
|
+
responseText = `Phase: ${typedArgs.phase}`;
|
|
20874
|
+
}
|
|
20986
20875
|
return {
|
|
20987
20876
|
content: [
|
|
20988
20877
|
{
|
|
20989
20878
|
type: "text",
|
|
20990
|
-
text:
|
|
20879
|
+
text: responseText
|
|
20991
20880
|
}
|
|
20992
20881
|
]
|
|
20993
20882
|
};
|
|
20994
20883
|
});
|
|
20995
20884
|
const transport = new StdioServerTransport();
|
|
20996
20885
|
await server.connect(transport);
|
|
20997
|
-
console.error("Purple MCP server started");
|
|
20886
|
+
console.error("Purple MCP server started (v2.0.0 - unified purple_status)");
|
|
20998
20887
|
}
|
|
20999
20888
|
main().catch((error2) => {
|
|
21000
20889
|
console.error("Fatal error in MCP server:", error2);
|