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.
@@ -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: "purple_update_status",
20654
- description: "Update the Purple CLI status bar with current progress. Use this to keep users informed of agent activity without requiring them to read your output.",
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., "0 - Validation", "1 - Product Spec", "2 - Engineering", "3 - Implementation", "4 - Review")'
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/planning), "execute" (writing code), "review" (verifying work)'
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
- total: {
20679
+ // Overall progress
20680
+ completedTickets: {
20717
20681
  type: "number",
20718
- description: "Total number of tickets"
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
- completed: {
20684
+ totalTickets: {
20736
20685
  type: "number",
20737
- description: "Number of tickets completed so far"
20686
+ description: "Total number of tickets in the feature"
20738
20687
  },
20739
- total: {
20740
- type: "number",
20741
- description: "Total number of tickets"
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
- currentTicketName: {
20744
- type: "string",
20745
- description: 'Name or description of the current ticket being worked on (e.g., "AUTH-001: User Login")'
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
- ticketName: {
20697
+ qaCurrentTest: {
20792
20698
  type: "string",
20793
- description: 'The ticket name/description (e.g., "Firebase authentication service")'
20699
+ description: 'Status text (e.g., "Running unit tests" when active, "Passed" or "Failed" when complete)'
20794
20700
  },
20795
- agent: {
20796
- type: "string",
20797
- description: 'The agent name (e.g., "senior-engineer"). Defaults to "senior-engineer".'
20798
- }
20799
- },
20800
- required: ["ticketId"],
20801
- additionalProperties: false
20802
- }
20803
- },
20804
- {
20805
- name: "purple_progress_complete_ticket",
20806
- description: "Mark a ticket as completed and remove it from the active list. Call this when a ticket is done.",
20807
- inputSchema: {
20808
- type: "object",
20809
- properties: {
20810
- ticketId: {
20811
- type: "string",
20812
- description: 'The ticket ID (e.g., "FCB-003")'
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: "1.0.0"
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
- let payload;
20885
- switch (name) {
20886
- case "purple_update_status": {
20887
- const typedArgs = args;
20888
- payload = {
20889
- tool: name,
20890
- phase: typedArgs.phase,
20891
- agent: typedArgs.agent,
20892
- currentTicket: typedArgs.currentTicket,
20893
- totalTickets: typedArgs.totalTickets,
20894
- mode: typedArgs.mode,
20895
- activeTool: typedArgs.tool,
20896
- activeFile: typedArgs.activeFile
20897
- };
20898
- break;
20899
- }
20900
- case "purple_set_phase": {
20901
- const typedArgs = args;
20902
- payload = {
20903
- tool: name,
20904
- phase: typedArgs.phase
20905
- };
20906
- break;
20907
- }
20908
- case "purple_report_progress": {
20909
- const typedArgs = args;
20910
- payload = {
20911
- tool: name,
20912
- currentTicket: typedArgs.current,
20913
- totalTickets: typedArgs.total
20914
- };
20915
- break;
20916
- }
20917
- case "purple_ticket_status": {
20918
- const typedArgs = args;
20919
- payload = {
20920
- tool: name,
20921
- phase: typedArgs.phase,
20922
- // completed means how many are done, so current ticket is completed + 1
20923
- currentTicket: typedArgs.completed + 1,
20924
- totalTickets: typedArgs.total,
20925
- activeFile: typedArgs.currentTicketName
20926
- // Use activeFile to show ticket name
20927
- };
20928
- break;
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: "Status updated"
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "purple-ai",
3
- "version": "0.0.13",
3
+ "version": "0.0.14",
4
4
  "description": "Purple - AI-powered workspace management CLI that wraps Claude Code",
5
5
  "main": "bin/purple.js",
6
6
  "bin": {