@codemcp/workflows 6.4.0 → 6.5.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.
Files changed (122) hide show
  1. package/package.json +2 -2
  2. package/packages/cli/dist/{chunk-D2Q6Y3QQ.js → chunk-4AZGS2GG.js} +321 -388
  3. package/packages/cli/dist/{cli-DXJJF56V.js → cli-ZCCFBQTP.js} +3 -3
  4. package/packages/cli/dist/{dist-W7PPKVFG.js → dist-I6VSREAJ.js} +11 -5
  5. package/packages/cli/dist/{dist-W7VMGB3G.js → dist-MW7THWM3.js} +875 -1136
  6. package/packages/cli/dist/index.js +2 -2
  7. package/packages/cli/package.json +1 -1
  8. package/packages/cli/resources/workflows/bugfix.yaml +14 -0
  9. package/packages/cli/resources/workflows/epcc.yaml +12 -0
  10. package/packages/cli/resources/workflows/greenfield.yaml +16 -0
  11. package/packages/cli/resources/workflows/minor.yaml +8 -0
  12. package/packages/cli/resources/workflows/tdd.yaml +10 -0
  13. package/packages/cli/resources/workflows/waterfall.yaml +16 -0
  14. package/packages/core/dist/beads-integration.d.ts +3 -5
  15. package/packages/core/dist/beads-integration.js +29 -35
  16. package/packages/core/dist/beads-integration.js.map +1 -1
  17. package/packages/core/dist/beads-state-manager.d.ts +3 -1
  18. package/packages/core/dist/beads-state-manager.js +17 -15
  19. package/packages/core/dist/beads-state-manager.js.map +1 -1
  20. package/packages/core/dist/file-detection-manager.js +15 -22
  21. package/packages/core/dist/file-detection-manager.js.map +1 -1
  22. package/packages/core/dist/index.d.ts +1 -0
  23. package/packages/core/dist/index.js +1 -0
  24. package/packages/core/dist/index.js.map +1 -1
  25. package/packages/core/dist/instruction-generator.d.ts +3 -7
  26. package/packages/core/dist/instruction-generator.js +17 -25
  27. package/packages/core/dist/instruction-generator.js.map +1 -1
  28. package/packages/core/dist/interfaces/instruction-generator.interface.d.ts +13 -4
  29. package/packages/core/dist/interfaces/plan-manager.interface.d.ts +9 -0
  30. package/packages/core/dist/logger.d.ts +49 -20
  31. package/packages/core/dist/logger.js +65 -141
  32. package/packages/core/dist/logger.js.map +1 -1
  33. package/packages/core/dist/plan-manager.d.ts +6 -4
  34. package/packages/core/dist/plan-manager.js +19 -15
  35. package/packages/core/dist/plan-manager.js.map +1 -1
  36. package/packages/core/dist/project-docs-manager.d.ts +3 -1
  37. package/packages/core/dist/project-docs-manager.js +11 -9
  38. package/packages/core/dist/project-docs-manager.js.map +1 -1
  39. package/packages/core/dist/state-machine-loader.d.ts +16 -0
  40. package/packages/core/dist/state-machine-loader.js +29 -0
  41. package/packages/core/dist/state-machine-loader.js.map +1 -1
  42. package/packages/core/dist/state-machine-types.d.ts +8 -0
  43. package/packages/core/dist/string-utils.d.ts +8 -0
  44. package/packages/core/dist/string-utils.js +14 -0
  45. package/packages/core/dist/string-utils.js.map +1 -0
  46. package/packages/core/dist/task-backend.d.ts +6 -3
  47. package/packages/core/dist/task-backend.js +10 -8
  48. package/packages/core/dist/task-backend.js.map +1 -1
  49. package/packages/core/dist/transition-engine.d.ts +3 -6
  50. package/packages/core/dist/transition-engine.js +31 -76
  51. package/packages/core/dist/transition-engine.js.map +1 -1
  52. package/packages/core/dist/workflow-manager.d.ts +2 -0
  53. package/packages/core/dist/workflow-manager.js +14 -2
  54. package/packages/core/dist/workflow-manager.js.map +1 -1
  55. package/packages/core/package.json +1 -1
  56. package/packages/core/resources/workflows/bugfix.yaml +14 -0
  57. package/packages/core/resources/workflows/epcc.yaml +12 -0
  58. package/packages/core/resources/workflows/greenfield.yaml +16 -0
  59. package/packages/core/resources/workflows/minor.yaml +8 -0
  60. package/packages/core/resources/workflows/tdd.yaml +10 -0
  61. package/packages/core/resources/workflows/waterfall.yaml +16 -0
  62. package/packages/docs/.vitepress/dist/workflows/bugfix.yaml +14 -0
  63. package/packages/docs/.vitepress/dist/workflows/epcc.yaml +12 -0
  64. package/packages/docs/.vitepress/dist/workflows/greenfield.yaml +16 -0
  65. package/packages/docs/.vitepress/dist/workflows/minor.yaml +8 -0
  66. package/packages/docs/.vitepress/dist/workflows/tdd.yaml +10 -0
  67. package/packages/docs/.vitepress/dist/workflows/waterfall.yaml +16 -0
  68. package/packages/docs/package.json +1 -1
  69. package/packages/mcp-server/dist/index.d.ts +1027 -0
  70. package/packages/mcp-server/dist/index.js +879 -1140
  71. package/packages/mcp-server/package.json +1 -1
  72. package/packages/mcp-server/resources/workflows/bugfix.yaml +14 -0
  73. package/packages/mcp-server/resources/workflows/epcc.yaml +12 -0
  74. package/packages/mcp-server/resources/workflows/greenfield.yaml +16 -0
  75. package/packages/mcp-server/resources/workflows/minor.yaml +8 -0
  76. package/packages/mcp-server/resources/workflows/tdd.yaml +10 -0
  77. package/packages/mcp-server/resources/workflows/waterfall.yaml +16 -0
  78. package/packages/opencode-plugin/dist/index.d.ts +9 -0
  79. package/packages/opencode-plugin/dist/index.js +11 -0
  80. package/packages/opencode-plugin/dist/index.js.map +1 -0
  81. package/packages/opencode-plugin/dist/opencode-logger.d.ts +21 -0
  82. package/packages/opencode-plugin/dist/opencode-logger.js +104 -0
  83. package/packages/opencode-plugin/dist/opencode-logger.js.map +1 -0
  84. package/packages/opencode-plugin/dist/plugin.d.ts +23 -0
  85. package/packages/opencode-plugin/dist/plugin.js +395 -0
  86. package/packages/opencode-plugin/dist/plugin.js.map +1 -0
  87. package/packages/opencode-plugin/dist/server-context.d.ts +40 -0
  88. package/packages/opencode-plugin/dist/server-context.js +96 -0
  89. package/packages/opencode-plugin/dist/server-context.js.map +1 -0
  90. package/packages/opencode-plugin/dist/tool-handlers/conduct-review.d.ts +3 -0
  91. package/packages/opencode-plugin/dist/tool-handlers/conduct-review.js +37 -0
  92. package/packages/opencode-plugin/dist/tool-handlers/conduct-review.js.map +1 -0
  93. package/packages/opencode-plugin/dist/tool-handlers/proceed-to-phase.d.ts +3 -0
  94. package/packages/opencode-plugin/dist/tool-handlers/proceed-to-phase.js +74 -0
  95. package/packages/opencode-plugin/dist/tool-handlers/proceed-to-phase.js.map +1 -0
  96. package/packages/opencode-plugin/dist/tool-handlers/reset-development.d.ts +3 -0
  97. package/packages/opencode-plugin/dist/tool-handlers/reset-development.js +63 -0
  98. package/packages/opencode-plugin/dist/tool-handlers/reset-development.js.map +1 -0
  99. package/packages/opencode-plugin/dist/tool-handlers/setup-project-docs.d.ts +3 -0
  100. package/packages/opencode-plugin/dist/tool-handlers/setup-project-docs.js +74 -0
  101. package/packages/opencode-plugin/dist/tool-handlers/setup-project-docs.js.map +1 -0
  102. package/packages/opencode-plugin/dist/tool-handlers/start-development.d.ts +3 -0
  103. package/packages/opencode-plugin/dist/tool-handlers/start-development.js +69 -0
  104. package/packages/opencode-plugin/dist/tool-handlers/start-development.js.map +1 -0
  105. package/packages/opencode-plugin/dist/tool-handlers/tool-helper.d.ts +10 -0
  106. package/packages/opencode-plugin/dist/tool-handlers/tool-helper.js +7 -0
  107. package/packages/opencode-plugin/dist/tool-handlers/tool-helper.js.map +1 -0
  108. package/packages/opencode-plugin/dist/types.d.ts +193 -0
  109. package/packages/opencode-plugin/dist/types.js +8 -0
  110. package/packages/opencode-plugin/dist/types.js.map +1 -0
  111. package/packages/opencode-plugin/dist/utils.d.ts +14 -0
  112. package/packages/opencode-plugin/dist/utils.js +26 -0
  113. package/packages/opencode-plugin/dist/utils.js.map +1 -0
  114. package/packages/opencode-plugin/package.json +52 -0
  115. package/packages/opencode-tui-plugin/package.json +46 -0
  116. package/packages/visualizer/package.json +1 -1
  117. package/resources/workflows/bugfix.yaml +14 -0
  118. package/resources/workflows/epcc.yaml +12 -0
  119. package/resources/workflows/greenfield.yaml +16 -0
  120. package/resources/workflows/minor.yaml +8 -0
  121. package/resources/workflows/tdd.yaml +10 -0
  122. package/resources/workflows/waterfall.yaml +16 -0
@@ -4087,16 +4087,13 @@ import { SetLevelRequestSchema } from "@modelcontextprotocol/sdk/types.js";
4087
4087
  import * as path4 from "path";
4088
4088
  import { homedir } from "os";
4089
4089
  import { execSync as execSync5 } from "child_process";
4090
- import { writeFile as writeFile4, readFile as readFile4, access as access6 } from "fs/promises";
4091
- import { dirname as dirname6 } from "path";
4092
- import { mkdir as mkdir4 } from "fs/promises";
4093
4090
  import { basename as basename4 } from "path";
4094
4091
  import { readFileSync, writeFileSync, existsSync as existsSync3, mkdirSync } from "fs";
4095
- import { readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
4092
+ import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
4096
4093
  import { resolve as resolve3 } from "path";
4097
4094
  import { execSync as execSync6 } from "child_process";
4098
4095
  import { readFileSync as readFileSync2 } from "fs";
4099
- import { join as join8, dirname as dirname7 } from "path";
4096
+ import { join as join8, dirname as dirname6 } from "path";
4100
4097
  import { fileURLToPath as fileURLToPath4 } from "url";
4101
4098
  import fs5 from "fs";
4102
4099
  import path5 from "path";
@@ -6737,25 +6734,21 @@ var LogLevel;
6737
6734
  LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
6738
6735
  LogLevel2[LogLevel2["SILENT"] = 4] = "SILENT";
6739
6736
  })(LogLevel || (LogLevel = {}));
6740
- var mcpServerInstance = null;
6737
+ var logSinkInstance = null;
6741
6738
  var currentLoggingLevel = null;
6742
6739
  function isTestMode() {
6743
- if (process.env.NODE_ENV === "test" || process.env.VITEST === "true") {
6740
+ if (process.env["NODE_ENV"] === "test" || process.env["VITEST"] === "true") {
6744
6741
  return true;
6745
6742
  }
6746
- const cwd = process.cwd();
6747
- if (cwd.includes("/tmp/") || cwd.includes("temp") || cwd.includes("test-")) {
6748
- return true;
6749
- }
6750
- if (process.env.LOG_LEVEL === "ERROR") {
6743
+ if (process.env["LOG_LEVEL"] === "ERROR") {
6751
6744
  return true;
6752
6745
  }
6753
6746
  return false;
6754
6747
  }
6755
- function setMcpServerForLogging(server) {
6756
- mcpServerInstance = server;
6748
+ function registerLogSink(sink) {
6749
+ logSinkInstance = sink;
6757
6750
  }
6758
- function setMcpLoggingLevel(level) {
6751
+ function setLoggingLevelFromString(level) {
6759
6752
  const levelMap = {
6760
6753
  debug: LogLevel.DEBUG,
6761
6754
  info: LogLevel.INFO,
@@ -6795,7 +6788,7 @@ var Logger = class _Logger {
6795
6788
  return LogLevel.INFO;
6796
6789
  }
6797
6790
  getLogLevelFromEnv() {
6798
- const envLevel = process.env.LOG_LEVEL?.toUpperCase();
6791
+ const envLevel = process.env["LOG_LEVEL"]?.toUpperCase();
6799
6792
  switch (envLevel) {
6800
6793
  case "DEBUG":
6801
6794
  return LogLevel.DEBUG;
@@ -6820,31 +6813,15 @@ var Logger = class _Logger {
6820
6813
  return `[${timestamp2}] ${level.toUpperCase()} [${this.component}] ${message}${contextStr}`;
6821
6814
  }
6822
6815
  /**
6823
- * Send log message to MCP client if server is available and level is appropriate
6816
+ * Send log message to registered sink if available
6824
6817
  */
6825
- async sendMcpLogMessage(level, message, context) {
6826
- if (mcpServerInstance) {
6818
+ async sendToSink(level, message, context) {
6819
+ if (logSinkInstance) {
6827
6820
  try {
6828
- let logData = message;
6829
- if (context) {
6830
- try {
6831
- const contextStr = JSON.stringify(context, null, 0);
6832
- logData = `${message} ${contextStr}`;
6833
- } catch (_error) {
6834
- logData = `${message} [context serialization failed]`;
6835
- }
6836
- }
6837
- await mcpServerInstance.server.notification({
6838
- method: "notifications/message",
6839
- params: {
6840
- level,
6841
- logger: this.component,
6842
- data: logData
6843
- }
6844
- });
6821
+ await logSinkInstance.log(level, this.component, message, context);
6845
6822
  } catch (error) {
6846
6823
  if (!isTestMode()) {
6847
- process.stderr.write(`[MCP-LOG-ERROR] Failed to send log notification: ${error}
6824
+ process.stderr.write(`[LOG-SINK-ERROR] Failed to send log to sink: ${error}
6848
6825
  `);
6849
6826
  }
6850
6827
  }
@@ -6852,85 +6829,42 @@ var Logger = class _Logger {
6852
6829
  }
6853
6830
  debug(message, context) {
6854
6831
  if (this.shouldLog(LogLevel.DEBUG)) {
6855
- const formattedMessage = this.formatMessage("debug", message, context);
6856
- process.stderr.write(formattedMessage + "\n");
6857
- this.sendMcpLogMessage("debug", message, context).catch(() => {
6832
+ if (!logSinkInstance) {
6833
+ const formattedMessage = this.formatMessage("debug", message, context);
6834
+ process.stderr.write(formattedMessage + "\n");
6835
+ }
6836
+ this.sendToSink("debug", message, context).catch(() => {
6858
6837
  });
6859
6838
  }
6860
6839
  }
6861
6840
  info(message, context) {
6862
6841
  if (this.shouldLog(LogLevel.INFO)) {
6863
- const formattedMessage = this.formatMessage("info", message, context);
6864
- process.stderr.write(formattedMessage + "\n");
6865
- this.sendEnhancedMcpNotification("info", message, context).catch(() => {
6866
- });
6867
- }
6868
- }
6869
- /**
6870
- * Send enhanced MCP notifications with better formatting for important events
6871
- */
6872
- async sendEnhancedMcpNotification(level, message, context) {
6873
- if (mcpServerInstance) {
6874
- try {
6875
- let enhancedMessage = message;
6876
- let notificationLevel = level;
6877
- if (context && (context.from || context.to) && message.includes("transition")) {
6878
- const from = context.from ? this.capitalizePhase(context.from) : "";
6879
- const to = context.to ? this.capitalizePhase(context.to) : "";
6880
- if (from && to) {
6881
- enhancedMessage = `Phase Transition: ${from} \u2192 ${to}`;
6882
- notificationLevel = "info";
6883
- }
6884
- }
6885
- if (message.includes("initialized successfully")) {
6886
- enhancedMessage = "\u{1F680} Vibe Feature MCP Server Ready";
6887
- notificationLevel = "info";
6888
- }
6889
- let logData = enhancedMessage;
6890
- if (context) {
6891
- try {
6892
- const contextStr = JSON.stringify(context, null, 0);
6893
- logData = `${enhancedMessage} ${contextStr}`;
6894
- } catch (_error) {
6895
- logData = `${enhancedMessage} [context serialization failed]`;
6896
- }
6897
- }
6898
- await mcpServerInstance.server.notification({
6899
- method: "notifications/message",
6900
- params: {
6901
- level: notificationLevel,
6902
- logger: this.component,
6903
- data: logData
6904
- }
6905
- });
6906
- } catch (error) {
6907
- if (!isTestMode()) {
6908
- process.stderr.write(`[MCP-LOG-ERROR] Failed to send log notification: ${error}
6909
- `);
6910
- }
6842
+ if (!logSinkInstance) {
6843
+ const formattedMessage = this.formatMessage("info", message, context);
6844
+ process.stderr.write(formattedMessage + "\n");
6911
6845
  }
6846
+ this.sendToSink("info", message, context).catch(() => {
6847
+ });
6912
6848
  }
6913
6849
  }
6914
- /**
6915
- * Capitalize phase name for display
6916
- */
6917
- capitalizePhase(phase) {
6918
- return phase.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
6919
- }
6920
6850
  warn(message, context) {
6921
6851
  if (this.shouldLog(LogLevel.WARN)) {
6922
- const formattedMessage = this.formatMessage("warn", message, context);
6923
- process.stderr.write(formattedMessage + "\n");
6924
- this.sendEnhancedMcpNotification("warning", message, context).catch(() => {
6852
+ if (!logSinkInstance) {
6853
+ const formattedMessage = this.formatMessage("warn", message, context);
6854
+ process.stderr.write(formattedMessage + "\n");
6855
+ }
6856
+ this.sendToSink("warning", message, context).catch(() => {
6925
6857
  });
6926
6858
  }
6927
6859
  }
6928
6860
  error(message, error, context) {
6929
6861
  if (this.shouldLog(LogLevel.ERROR)) {
6930
6862
  const errorContext = error ? { ...context, error: error.message, stack: error.stack } : context;
6931
- const formattedMessage = this.formatMessage("error", message, errorContext);
6932
- process.stderr.write(formattedMessage + "\n");
6933
- this.sendEnhancedMcpNotification("error", message, errorContext).catch(() => {
6863
+ if (!logSinkInstance) {
6864
+ const formattedMessage = this.formatMessage("error", message, errorContext);
6865
+ process.stderr.write(formattedMessage + "\n");
6866
+ }
6867
+ this.sendToSink("error", message, errorContext).catch(() => {
6934
6868
  });
6935
6869
  }
6936
6870
  }
@@ -6941,7 +6875,7 @@ var Logger = class _Logger {
6941
6875
  function createLogger(component, logLevel) {
6942
6876
  return new Logger(component, logLevel);
6943
6877
  }
6944
- var logger = createLogger("VibeFeatureMCP");
6878
+ var logger = createLogger("workflows-core");
6945
6879
  var logger2 = createLogger("StateMachineLoader");
6946
6880
  var StateMachineLoader = class {
6947
6881
  stateMachine = null;
@@ -7165,6 +7099,35 @@ ${continueTransition.additional_instructions}`;
7165
7099
  }
7166
7100
  return stateDefinition.default_instructions;
7167
7101
  }
7102
+ /**
7103
+ * Get allowed file patterns for a specific phase.
7104
+ * Returns undefined if no restrictions are defined (all files allowed).
7105
+ *
7106
+ * @param phase - The phase/state name to get patterns for
7107
+ * @returns Array of glob patterns or undefined if all files are allowed
7108
+ */
7109
+ getAllowedFilePatterns(phase) {
7110
+ if (!this.stateMachine) {
7111
+ throw new Error("State machine not loaded");
7112
+ }
7113
+ const stateDefinition = this.stateMachine.states[phase];
7114
+ if (!stateDefinition) {
7115
+ logger2.error("Unknown phase", new Error(`Unknown phase: ${phase}`));
7116
+ throw new Error(`Unknown phase: ${phase}`);
7117
+ }
7118
+ return stateDefinition.allowed_file_patterns;
7119
+ }
7120
+ /**
7121
+ * Whether the given phase restricts which files may be edited.
7122
+ * Returns false when no allowed_file_patterns are defined (all files allowed).
7123
+ * Callers should use getAllowedFilePatterns + a glob library for actual path matching.
7124
+ *
7125
+ * @param phase - The phase/state name
7126
+ */
7127
+ hasFileRestrictions(phase) {
7128
+ const patterns = this.getAllowedFilePatterns(phase);
7129
+ return patterns !== void 0 && patterns.length > 0;
7130
+ }
7168
7131
  };
7169
7132
  var logger3 = createLogger("ConfigManager");
7170
7133
  var ConfigManager = class {
@@ -7234,13 +7197,21 @@ var WorkflowManager = class _WorkflowManager {
7234
7197
  }
7235
7198
  /**
7236
7199
  * Parse enabled domains from environment variable
7200
+ * Supports both WORKFLOW_DOMAINS and VIBE_WORKFLOW_DOMAINS (legacy)
7201
+ * WORKFLOW_DOMAINS takes precedence if both are set (modern, non-prefixed version preferred)
7237
7202
  */
7238
7203
  parseEnabledDomains() {
7239
- const domainsEnv = process.env["VIBE_WORKFLOW_DOMAINS"];
7204
+ const domainsEnv = process.env["WORKFLOW_DOMAINS"] || process.env["VIBE_WORKFLOW_DOMAINS"];
7240
7205
  if (!domainsEnv) {
7206
+ logger4.debug("No domain configuration found, using default: code");
7241
7207
  return /* @__PURE__ */ new Set(["code"]);
7242
7208
  }
7243
- return new Set(domainsEnv.split(",").map((d) => d.trim()).filter((d) => d));
7209
+ const domains = new Set(domainsEnv.split(",").map((d) => d.trim()).filter((d) => d));
7210
+ logger4.debug("Parsed enabled domains", {
7211
+ source: process.env["WORKFLOW_DOMAINS"] ? "WORKFLOW_DOMAINS" : "VIBE_WORKFLOW_DOMAINS",
7212
+ domains: Array.from(domains)
7213
+ });
7214
+ return domains;
7244
7215
  }
7245
7216
  /**
7246
7217
  * Load project-specific workflows from .vibe/workflows/
@@ -7612,15 +7583,18 @@ var WorkflowManager = class _WorkflowManager {
7612
7583
  return false;
7613
7584
  }
7614
7585
  };
7615
- var logger5 = createLogger("TransitionEngine");
7586
+ function capitalizePhase(phase) {
7587
+ return phase.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
7588
+ }
7589
+ var defaultLogger = createLogger("TransitionEngine");
7616
7590
  var TransitionEngine = class {
7617
- stateMachineLoader;
7618
7591
  workflowManager;
7592
+ logger;
7619
7593
  conversationManager;
7620
- constructor(projectPath) {
7621
- this.stateMachineLoader = new StateMachineLoader();
7594
+ constructor(projectPath, logger24 = defaultLogger) {
7622
7595
  this.workflowManager = new WorkflowManager();
7623
- logger5.info("TransitionEngine initialized", { projectPath });
7596
+ this.logger = logger24;
7597
+ this.logger.info("TransitionEngine initialized", { projectPath });
7624
7598
  }
7625
7599
  /**
7626
7600
  * Set the conversation manager (dependency injection)
@@ -7639,11 +7613,11 @@ var TransitionEngine = class {
7639
7613
  */
7640
7614
  async isFirstCallFromInitialState(context) {
7641
7615
  if (!this.conversationManager) {
7642
- logger5.warn("ConversationManager not set, assuming first call");
7616
+ this.logger.warn("ConversationManager not set, assuming first call");
7643
7617
  return true;
7644
7618
  }
7645
7619
  const hasInteractions = await this.conversationManager.hasInteractions(context.conversationId);
7646
- logger5.debug("Checking first call from initial state", {
7620
+ this.logger.debug("Checking first call from initial state", {
7647
7621
  hasInteractions,
7648
7622
  conversationId: context.conversationId,
7649
7623
  currentPhase: context.currentPhase
@@ -7653,51 +7627,18 @@ var TransitionEngine = class {
7653
7627
  /**
7654
7628
  * Generate instructions for defining phase entrance criteria
7655
7629
  */
7656
- async generateCriteriaDefinitionInstructions(projectPath, conversationId) {
7657
- const conversationState = await this.conversationManager?.getConversationState(conversationId);
7658
- const workflowName = conversationState?.workflowName;
7659
- const stateMachine = this.workflowManager.loadWorkflowForProject(projectPath, workflowName);
7630
+ generateCriteriaDefinitionInstructions(stateMachine) {
7660
7631
  const phases = Object.keys(stateMachine.states);
7661
- let instructions = `Welcome to ${stateMachine.name}!
7662
-
7663
- Before we begin development, let's establish clear entrance criteria for each phase. This will help us make informed decisions about when to transition between phases throughout the development process.
7664
-
7665
- Please update the plan file with a "Phase Entrance Criteria" section that defines specific, measurable criteria for entering each phase:
7666
-
7667
- ## Phase Entrance Criteria
7668
-
7669
- `;
7670
- for (const phase of phases) {
7671
- if (phase === stateMachine.initial_state)
7672
- continue;
7673
- const phaseDefinition = stateMachine.states[phase];
7674
- const capitalizedPhase = this.capitalizePhase(phase);
7675
- instructions += `### ${capitalizedPhase} Phase
7676
- *${phaseDefinition.description}*
7677
-
7678
- **Enter when:**
7679
- - [ ] [Define specific criteria for entering ${phase} phase]
7680
- - [ ] [Add measurable conditions that must be met]
7681
- - [ ] [Include any deliverables or milestones required]
7682
-
7683
- `;
7684
- }
7685
- instructions += `
7686
- Once you've defined these criteria, we can begin development. Throughout the process, consult these criteria when considering phase transitions.
7687
-
7688
- **Remember**: These criteria should be specific and measurable so we can clearly determine when each phase is ready to begin.`;
7689
- return instructions;
7632
+ const phaseList = phases.filter((phase) => phase !== stateMachine.initial_state).map((phase) => capitalizePhase(phase)).join(", ");
7633
+ return `Define entrance criteria for each phase (${phaseList}) in the plan file. Criteria should be specific and measurable.`;
7690
7634
  }
7691
7635
  /**
7692
7636
  * Get phase-specific instructions for continuing work in current phase
7693
7637
  */
7694
- async getContinuePhaseInstructions(phase, projectPath, conversationId) {
7695
- const conversationState = await this.conversationManager?.getConversationState(conversationId);
7696
- const workflowName = conversationState?.workflowName;
7697
- const stateMachine = this.workflowManager.loadWorkflowForProject(projectPath, workflowName);
7638
+ getContinuePhaseInstructions(phase, stateMachine) {
7698
7639
  const stateDefinition = stateMachine.states[phase];
7699
7640
  if (!stateDefinition) {
7700
- logger5.error("Unknown phase", new Error(`Unknown phase: ${phase}`));
7641
+ this.logger.error("Unknown phase", new Error(`Unknown phase: ${phase}`));
7701
7642
  throw new Error(`Unknown phase: ${phase}`);
7702
7643
  }
7703
7644
  const continueTransition = stateDefinition.transitions.find((t) => t.to === phase);
@@ -7720,19 +7661,17 @@ ${continueTransition.additional_instructions}`;
7720
7661
  /**
7721
7662
  * Get the first development phase from the state machine
7722
7663
  */
7723
- async getFirstDevelopmentPhase(projectPath, conversationId) {
7724
- const conversationState = await this.conversationManager?.getConversationState(conversationId);
7725
- const workflowName = conversationState?.workflowName;
7726
- const stateMachine = this.workflowManager.loadWorkflowForProject(projectPath, workflowName);
7727
- const initialState = stateMachine.initial_state;
7728
- return initialState;
7664
+ getFirstDevelopmentPhase(stateMachine) {
7665
+ return stateMachine.initial_state;
7729
7666
  }
7730
7667
  /**
7731
7668
  * Analyze context and determine appropriate phase transition
7732
7669
  */
7733
7670
  async analyzePhaseTransition(context) {
7734
7671
  const { currentPhase, projectPath, conversationId, userInput, context: additionalContext, conversationSummary } = context;
7735
- logger5.debug("Analyzing phase transition", {
7672
+ const conversationState = await this.conversationManager?.getConversationState(conversationId);
7673
+ const stateMachine = this.workflowManager.loadWorkflowForProject(projectPath, conversationState?.workflowName);
7674
+ this.logger.debug("Analyzing phase transition", {
7736
7675
  currentPhase,
7737
7676
  projectPath,
7738
7677
  hasUserInput: !!userInput,
@@ -7741,14 +7680,14 @@ ${continueTransition.additional_instructions}`;
7741
7680
  userInput: userInput ? userInput.substring(0, 50) + (userInput.length > 50 ? "..." : "") : void 0
7742
7681
  });
7743
7682
  if (await this.isFirstCallFromInitialState(context)) {
7744
- const firstDevelopmentPhase = await this.getFirstDevelopmentPhase(projectPath, conversationId);
7745
- logger5.info("First call from initial state - transitioning to first development phase with criteria", {
7683
+ const firstDevelopmentPhase = this.getFirstDevelopmentPhase(stateMachine);
7684
+ this.logger.info("First call from initial state - transitioning to first development phase with criteria", {
7746
7685
  currentPhase,
7747
7686
  firstDevelopmentPhase,
7748
7687
  projectPath
7749
7688
  });
7750
- const criteriaInstructions = await this.generateCriteriaDefinitionInstructions(projectPath, conversationId);
7751
- const phaseInstructions = await this.getContinuePhaseInstructions(firstDevelopmentPhase, projectPath, conversationId);
7689
+ const criteriaInstructions = this.generateCriteriaDefinitionInstructions(stateMachine);
7690
+ const phaseInstructions = this.getContinuePhaseInstructions(firstDevelopmentPhase, stateMachine);
7752
7691
  return {
7753
7692
  newPhase: firstDevelopmentPhase,
7754
7693
  // Transition to first development phase
@@ -7757,8 +7696,8 @@ ${continueTransition.additional_instructions}`;
7757
7696
  isModeled: true
7758
7697
  };
7759
7698
  }
7760
- const continueInstructions = await this.getContinuePhaseInstructions(currentPhase, projectPath, conversationId);
7761
- logger5.debug("Continuing in current phase - LLM will evaluate transition criteria", {
7699
+ const continueInstructions = this.getContinuePhaseInstructions(currentPhase, stateMachine);
7700
+ this.logger.debug("Continuing in current phase - LLM will evaluate transition criteria", {
7762
7701
  currentPhase,
7763
7702
  projectPath
7764
7703
  });
@@ -7774,7 +7713,7 @@ ${continueTransition.additional_instructions}`;
7774
7713
  */
7775
7714
  handleExplicitTransition(currentPhase, targetPhase, projectPath, reason, workflowName) {
7776
7715
  const stateMachine = this.getStateMachine(projectPath, workflowName);
7777
- logger5.debug("Handling explicit phase transition", {
7716
+ this.logger.debug("Handling explicit phase transition", {
7778
7717
  currentPhase,
7779
7718
  targetPhase,
7780
7719
  projectPath,
@@ -7785,7 +7724,7 @@ ${continueTransition.additional_instructions}`;
7785
7724
  if (!stateMachine.states[normalizedTargetPhase]) {
7786
7725
  const validPhases = Object.keys(stateMachine.states);
7787
7726
  const errorMsg = `Invalid target phase: "${targetPhase}". Valid phases are: ${validPhases.join(", ")}`;
7788
- logger5.error("Invalid target phase", new Error(errorMsg));
7727
+ this.logger.error("Invalid target phase", new Error(errorMsg));
7789
7728
  throw new Error(errorMsg);
7790
7729
  }
7791
7730
  const targetState = stateMachine.states[normalizedTargetPhase];
@@ -7796,7 +7735,7 @@ ${continueTransition.additional_instructions}`;
7796
7735
  isModeled: false
7797
7736
  // Direct phase transitions are not modeled
7798
7737
  };
7799
- logger5.info("Explicit phase transition processed", {
7738
+ this.logger.info("Explicit phase transition processed", {
7800
7739
  fromPhase: currentPhase,
7801
7740
  toPhase: normalizedTargetPhase,
7802
7741
  reason: transitionInfo.transitionReason,
@@ -7809,12 +7748,6 @@ ${continueTransition.additional_instructions}`;
7809
7748
  isModeled: transitionInfo.isModeled
7810
7749
  };
7811
7750
  }
7812
- /**
7813
- * Capitalize phase name for display
7814
- */
7815
- capitalizePhase(phase) {
7816
- return phase.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
7817
- }
7818
7751
  /**
7819
7752
  * Filter transitions based on agent role (for crowd workflows)
7820
7753
  * Returns transitions applicable to the current agent
@@ -7826,7 +7759,7 @@ ${continueTransition.additional_instructions}`;
7826
7759
  return transitions.filter((t) => !t.role || t.role === agentRole);
7827
7760
  }
7828
7761
  };
7829
- var logger6 = createLogger("FileStorage");
7762
+ var logger5 = createLogger("FileStorage");
7830
7763
  var FileStorage = class {
7831
7764
  conversationsDir;
7832
7765
  basePath;
@@ -7844,11 +7777,11 @@ var FileStorage = class {
7844
7777
  async initialize() {
7845
7778
  try {
7846
7779
  await fs4.mkdir(this.conversationsDir, { recursive: true });
7847
- logger6.debug("FileStorage initialized", {
7780
+ logger5.debug("FileStorage initialized", {
7848
7781
  conversationsDir: this.conversationsDir
7849
7782
  });
7850
7783
  } catch (error) {
7851
- logger6.error("Failed to initialize FileStorage", error);
7784
+ logger5.error("Failed to initialize FileStorage", error);
7852
7785
  throw error;
7853
7786
  }
7854
7787
  }
@@ -7898,12 +7831,12 @@ var FileStorage = class {
7898
7831
  await fs4.mkdir(conversationDir, { recursive: true });
7899
7832
  const stateJson = JSON.stringify(state, null, 2);
7900
7833
  await this.writeAtomic(stateFilePath, stateJson);
7901
- logger6.debug("Conversation state saved", {
7834
+ logger5.debug("Conversation state saved", {
7902
7835
  conversationId: state.conversationId,
7903
7836
  currentPhase: state.currentPhase
7904
7837
  });
7905
7838
  } catch (error) {
7906
- logger6.error("Failed to save conversation state", error, {
7839
+ logger5.error("Failed to save conversation state", error, {
7907
7840
  conversationId: state.conversationId
7908
7841
  });
7909
7842
  throw error;
@@ -7923,7 +7856,7 @@ var FileStorage = class {
7923
7856
  if (error.code === "ENOENT") {
7924
7857
  return null;
7925
7858
  }
7926
- logger6.warn("Failed to read conversation state, returning null", {
7859
+ logger5.warn("Failed to read conversation state, returning null", {
7927
7860
  conversationId,
7928
7861
  error: error.message
7929
7862
  });
@@ -7955,7 +7888,7 @@ var FileStorage = class {
7955
7888
  if (error.code === "ENOENT") {
7956
7889
  return [];
7957
7890
  }
7958
- logger6.error("Failed to get all conversation states", error);
7891
+ logger5.error("Failed to get all conversation states", error);
7959
7892
  throw error;
7960
7893
  }
7961
7894
  }
@@ -7967,13 +7900,13 @@ var FileStorage = class {
7967
7900
  const conversationDir = this.getConversationDir(conversationId);
7968
7901
  try {
7969
7902
  await fs4.rm(conversationDir, { recursive: true, force: true });
7970
- logger6.debug("Conversation state deleted", { conversationId });
7903
+ logger5.debug("Conversation state deleted", { conversationId });
7971
7904
  return true;
7972
7905
  } catch (error) {
7973
7906
  if (error.code === "ENOENT") {
7974
7907
  return false;
7975
7908
  }
7976
- logger6.error("Failed to delete conversation state", error, {
7909
+ logger5.error("Failed to delete conversation state", error, {
7977
7910
  conversationId
7978
7911
  });
7979
7912
  throw error;
@@ -7990,12 +7923,12 @@ var FileStorage = class {
7990
7923
  await fs4.mkdir(conversationDir, { recursive: true });
7991
7924
  const logLine = JSON.stringify(log) + "\n";
7992
7925
  await fs4.appendFile(interactionsFilePath, logLine, "utf-8");
7993
- logger6.debug("Interaction logged", {
7926
+ logger5.debug("Interaction logged", {
7994
7927
  conversationId: log.conversationId,
7995
7928
  toolName: log.toolName
7996
7929
  });
7997
7930
  } catch (error) {
7998
- logger6.error("Failed to log interaction", error, {
7931
+ logger5.error("Failed to log interaction", error, {
7999
7932
  conversationId: log.conversationId,
8000
7933
  toolName: log.toolName
8001
7934
  });
@@ -8017,7 +7950,7 @@ var FileStorage = class {
8017
7950
  const log = JSON.parse(line);
8018
7951
  logs.push(log);
8019
7952
  } catch {
8020
- logger6.warn("Skipping corrupted interaction log line", {
7953
+ logger5.warn("Skipping corrupted interaction log line", {
8021
7954
  conversationId
8022
7955
  });
8023
7956
  }
@@ -8027,7 +7960,7 @@ var FileStorage = class {
8027
7960
  if (error.code === "ENOENT") {
8028
7961
  return [];
8029
7962
  }
8030
- logger6.error("Failed to get interaction logs", error, {
7963
+ logger5.error("Failed to get interaction logs", error, {
8031
7964
  conversationId
8032
7965
  });
8033
7966
  throw error;
@@ -8047,12 +7980,12 @@ var FileStorage = class {
8047
7980
  const interactionsFilePath = this.getInteractionsFilePath(conversationId);
8048
7981
  try {
8049
7982
  await fs4.unlink(interactionsFilePath);
8050
- logger6.debug("Interaction logs deleted", { conversationId });
7983
+ logger5.debug("Interaction logs deleted", { conversationId });
8051
7984
  } catch (error) {
8052
7985
  if (error.code === "ENOENT") {
8053
7986
  return;
8054
7987
  }
8055
- logger6.warn("Failed to delete interaction logs", {
7988
+ logger5.warn("Failed to delete interaction logs", {
8056
7989
  conversationId,
8057
7990
  error: error.message
8058
7991
  });
@@ -8071,16 +8004,16 @@ var FileStorage = class {
8071
8004
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
8072
8005
  };
8073
8006
  await this.saveConversationState(updatedState);
8074
- logger6.debug("Conversation state reset", { conversationId });
8007
+ logger5.debug("Conversation state reset", { conversationId });
8075
8008
  }
8076
8009
  /**
8077
8010
  * Close file storage (no-op for file-based storage)
8078
8011
  */
8079
8012
  async close() {
8080
- logger6.debug("FileStorage closed");
8013
+ logger5.debug("FileStorage closed");
8081
8014
  }
8082
8015
  };
8083
- var logger7 = createLogger("PathValidationUtils");
8016
+ var logger6 = createLogger("PathValidationUtils");
8084
8017
  var PathValidationUtils = class {
8085
8018
  /**
8086
8019
  * Validate if a string is a known template name
@@ -8108,7 +8041,7 @@ var PathValidationUtils = class {
8108
8041
  error: "Path points to a directory, not a file"
8109
8042
  };
8110
8043
  }
8111
- logger7.debug("File path validated successfully", {
8044
+ logger6.debug("File path validated successfully", {
8112
8045
  originalPath: filePath,
8113
8046
  resolvedPath
8114
8047
  });
@@ -8118,7 +8051,7 @@ var PathValidationUtils = class {
8118
8051
  };
8119
8052
  } catch (error) {
8120
8053
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
8121
- logger7.debug("File path validation failed", {
8054
+ logger6.debug("File path validation failed", {
8122
8055
  filePath,
8123
8056
  error: errorMessage
8124
8057
  });
@@ -8148,7 +8081,7 @@ var PathValidationUtils = class {
8148
8081
  error: "Path is neither a file nor a directory"
8149
8082
  };
8150
8083
  }
8151
- logger7.debug("File or directory path validated successfully", {
8084
+ logger6.debug("File or directory path validated successfully", {
8152
8085
  originalPath: filePath,
8153
8086
  resolvedPath,
8154
8087
  isFile: stats.isFile(),
@@ -8160,7 +8093,7 @@ var PathValidationUtils = class {
8160
8093
  };
8161
8094
  } catch (error) {
8162
8095
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
8163
- logger7.debug("File or directory path validation failed", {
8096
+ logger6.debug("File or directory path validation failed", {
8164
8097
  filePath,
8165
8098
  error: errorMessage
8166
8099
  });
@@ -8270,7 +8203,7 @@ function getPathBasename(filePath, fallback = "unknown") {
8270
8203
  const result = basename(trimmedPath);
8271
8204
  return result || fallback;
8272
8205
  }
8273
- var logger8 = createLogger("PlanManager");
8206
+ var logger7 = createLogger("PlanManager");
8274
8207
  var PlanManager = class {
8275
8208
  stateMachine = null;
8276
8209
  /**
@@ -8278,7 +8211,7 @@ var PlanManager = class {
8278
8211
  */
8279
8212
  setStateMachine(stateMachine) {
8280
8213
  this.stateMachine = stateMachine;
8281
- logger8.debug("State machine set for plan manager", {
8214
+ logger7.debug("State machine set for plan manager", {
8282
8215
  name: stateMachine.name,
8283
8216
  phases: Object.keys(stateMachine.states)
8284
8217
  });
@@ -8287,7 +8220,7 @@ var PlanManager = class {
8287
8220
  * Set the task backend configuration
8288
8221
  */
8289
8222
  setTaskBackend(taskBackend) {
8290
- logger8.debug("Task backend set for plan manager (markdown mode)", {
8223
+ logger7.debug("Task backend set for plan manager (markdown mode)", {
8291
8224
  backend: taskBackend.backend,
8292
8225
  available: taskBackend.isAvailable
8293
8226
  });
@@ -8315,43 +8248,43 @@ var PlanManager = class {
8315
8248
  * Create initial plan file if it doesn't exist
8316
8249
  */
8317
8250
  async ensurePlanFile(planFilePath, projectPath, gitBranch) {
8318
- logger8.debug("Ensuring plan file exists", {
8251
+ logger7.debug("Ensuring plan file exists", {
8319
8252
  planFilePath,
8320
8253
  projectPath,
8321
8254
  gitBranch
8322
8255
  });
8323
8256
  const planInfo = await this.getPlanFileInfo(planFilePath);
8324
8257
  if (!planInfo.exists) {
8325
- logger8.info("Plan file not found, creating initial plan", {
8258
+ logger7.info("Plan file not found, creating initial plan", {
8326
8259
  planFilePath
8327
8260
  });
8328
8261
  await this.createInitialPlanFile(planFilePath, projectPath, gitBranch);
8329
- logger8.info("Initial plan file created successfully", { planFilePath });
8262
+ logger7.info("Initial plan file created successfully", { planFilePath });
8330
8263
  } else {
8331
- logger8.debug("Plan file already exists", { planFilePath });
8264
+ logger7.debug("Plan file already exists", { planFilePath });
8332
8265
  }
8333
8266
  }
8334
8267
  /**
8335
8268
  * Create initial plan file with template content
8336
8269
  */
8337
8270
  async createInitialPlanFile(planFilePath, projectPath, gitBranch) {
8338
- logger8.debug("Creating initial plan file", { planFilePath });
8271
+ logger7.debug("Creating initial plan file", { planFilePath });
8339
8272
  try {
8340
8273
  await mkdir(dirname2(planFilePath), { recursive: true });
8341
- logger8.debug("Plan file directory ensured", {
8274
+ logger7.debug("Plan file directory ensured", {
8342
8275
  directory: dirname2(planFilePath)
8343
8276
  });
8344
8277
  const projectName = getPathBasename(projectPath, "Unknown Project");
8345
8278
  const branchInfo = gitBranch !== "no-git" ? ` (${gitBranch} branch)` : "";
8346
8279
  const initialContent = this.generateInitialPlanContent(projectName, branchInfo);
8347
8280
  await writeFile(planFilePath, initialContent, "utf-8");
8348
- logger8.info("Initial plan file written successfully", {
8281
+ logger7.info("Initial plan file written successfully", {
8349
8282
  planFilePath,
8350
8283
  contentLength: initialContent.length,
8351
8284
  projectName
8352
8285
  });
8353
8286
  } catch (error) {
8354
- logger8.error("Failed to create initial plan file", error, {
8287
+ logger7.error("Failed to create initial plan file", error, {
8355
8288
  planFilePath
8356
8289
  });
8357
8290
  throw error;
@@ -8383,7 +8316,7 @@ var PlanManager = class {
8383
8316
  *Additional context and observations*
8384
8317
 
8385
8318
  `;
8386
- content += `## ${this.capitalizePhase(initialPhase)}
8319
+ content += `## ${capitalizePhase(initialPhase)}
8387
8320
  ### Tasks
8388
8321
  - [ ] *Tasks will be added as they are identified*
8389
8322
 
@@ -8393,7 +8326,7 @@ var PlanManager = class {
8393
8326
  `;
8394
8327
  for (const phase of phases) {
8395
8328
  if (phase !== initialPhase) {
8396
- content += `## ${this.capitalizePhase(phase)}
8329
+ content += `## ${capitalizePhase(phase)}
8397
8330
  ### Tasks
8398
8331
  - [ ] *To be added when this phase becomes active*
8399
8332
 
@@ -8445,31 +8378,31 @@ var PlanManager = class {
8445
8378
  }
8446
8379
  const phaseDefinition = this.stateMachine.states[phase];
8447
8380
  if (!phaseDefinition) {
8448
- logger8.warn("Unknown phase for plan file guidance", { phase });
8449
- return `Update the ${this.capitalizePhase(phase)} section with current progress and mark completed tasks.`;
8381
+ logger7.warn("Unknown phase for plan file guidance", { phase });
8382
+ return `Update the ${capitalizePhase(phase)} section with current progress and mark completed tasks.`;
8450
8383
  }
8451
- const capitalizedPhase = this.capitalizePhase(phase);
8384
+ const capitalizedPhase = capitalizePhase(phase);
8452
8385
  return `Update the ${capitalizedPhase} section with progress. Mark completed tasks with [x] and add new tasks as they are identified.`;
8453
8386
  }
8454
8387
  /**
8455
8388
  * Delete plan file
8456
8389
  */
8457
8390
  async deletePlanFile(planFilePath) {
8458
- logger8.debug("Deleting plan file", { planFilePath });
8391
+ logger7.debug("Deleting plan file", { planFilePath });
8459
8392
  try {
8460
8393
  await access2(planFilePath);
8461
8394
  const { unlink: unlink2 } = await import("fs/promises");
8462
8395
  await unlink2(planFilePath);
8463
- logger8.info("Plan file deleted successfully", { planFilePath });
8396
+ logger7.info("Plan file deleted successfully", { planFilePath });
8464
8397
  return true;
8465
8398
  } catch (error) {
8466
8399
  if (error.code === "ENOENT") {
8467
- logger8.debug("Plan file does not exist, nothing to delete", {
8400
+ logger7.debug("Plan file does not exist, nothing to delete", {
8468
8401
  planFilePath
8469
8402
  });
8470
8403
  return true;
8471
8404
  }
8472
- logger8.error("Failed to delete plan file", error, {
8405
+ logger7.error("Failed to delete plan file", error, {
8473
8406
  planFilePath
8474
8407
  });
8475
8408
  throw error;
@@ -8479,32 +8412,26 @@ var PlanManager = class {
8479
8412
  * Ensure plan file is deleted (verify deletion)
8480
8413
  */
8481
8414
  async ensurePlanFileDeleted(planFilePath) {
8482
- logger8.debug("Ensuring plan file is deleted", { planFilePath });
8415
+ logger7.debug("Ensuring plan file is deleted", { planFilePath });
8483
8416
  try {
8484
8417
  await access2(planFilePath);
8485
- logger8.warn("Plan file still exists after deletion attempt", {
8418
+ logger7.warn("Plan file still exists after deletion attempt", {
8486
8419
  planFilePath
8487
8420
  });
8488
8421
  return false;
8489
8422
  } catch (error) {
8490
8423
  if (error.code === "ENOENT") {
8491
- logger8.debug("Plan file successfully deleted (does not exist)", {
8424
+ logger7.debug("Plan file successfully deleted (does not exist)", {
8492
8425
  planFilePath
8493
8426
  });
8494
8427
  return true;
8495
8428
  }
8496
- logger8.error("Error checking plan file deletion", error, {
8429
+ logger7.error("Error checking plan file deletion", error, {
8497
8430
  planFilePath
8498
8431
  });
8499
8432
  throw error;
8500
8433
  }
8501
8434
  }
8502
- /**
8503
- * Capitalize phase name for display
8504
- */
8505
- capitalizePhase(phase) {
8506
- return phase.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
8507
- }
8508
8435
  /**
8509
8436
  * Generate workflow documentation URL for predefined workflows
8510
8437
  * Returns undefined for custom workflows
@@ -8515,8 +8442,22 @@ var PlanManager = class {
8515
8442
  }
8516
8443
  return `https://mrsimpson.github.io/responsible-vibe-mcp/workflows/${workflowName}`;
8517
8444
  }
8445
+ /**
8446
+ * Generate base instructions for the LLM after a workflow is started.
8447
+ * Instructs the LLM to populate the Goal section and define phase entrance
8448
+ * criteria in the freshly created plan file.
8449
+ */
8450
+ getInitialPlanGuidance(planFilePath, workflowDocUrl) {
8451
+ const docInfo = workflowDocUrl ? `
8452
+
8453
+ Inform the user about the chosen workflow. They can visit: ${workflowDocUrl} to get detailed information.` : "";
8454
+ const i18nNote = `
8455
+
8456
+ NOTE: If the user is communicating in a non-English language, translate plan file content to that language while keeping markdown headers (##, ###) in English to maintain structure parsing. Continue all interactions in the user's language.`;
8457
+ return `**Read ${planFilePath}** to understand the workflow structure. Add entrance criteria for each phase (what must be true to enter), then call \`whats_next()\`.${docInfo}${i18nNote}`;
8458
+ }
8518
8459
  };
8519
- var logger9 = createLogger("ConversationManager");
8460
+ var logger8 = createLogger("ConversationManager");
8520
8461
  var ConversationManager = class {
8521
8462
  database;
8522
8463
  projectPath;
@@ -8543,11 +8484,11 @@ var ConversationManager = class {
8543
8484
  async getConversationContext() {
8544
8485
  const projectPath = this.getProjectPath();
8545
8486
  const gitBranch = this.getGitBranch(projectPath);
8546
- logger9.debug("Getting conversation context", { projectPath, gitBranch });
8487
+ logger8.debug("Getting conversation context", { projectPath, gitBranch });
8547
8488
  const conversationId = this.generateConversationId(projectPath, gitBranch);
8548
8489
  const state = await this.database.getConversationState(conversationId);
8549
8490
  if (!state) {
8550
- logger9.warn("No conversation found for context", {
8491
+ logger8.warn("No conversation found for context", {
8551
8492
  projectPath,
8552
8493
  gitBranch,
8553
8494
  conversationId
@@ -8576,7 +8517,7 @@ var ConversationManager = class {
8576
8517
  async createConversationContext(workflowName, projectPathOverride) {
8577
8518
  const projectPath = projectPathOverride || this.getProjectPath();
8578
8519
  const gitBranch = this.getGitBranch(projectPath);
8579
- logger9.debug("Creating conversation context", {
8520
+ logger8.debug("Creating conversation context", {
8580
8521
  projectPath,
8581
8522
  gitBranch,
8582
8523
  workflowName
@@ -8586,14 +8527,14 @@ var ConversationManager = class {
8586
8527
  if (existingState) {
8587
8528
  if (existingState.workflowName !== workflowName) {
8588
8529
  const errorMessage = `Development conversation already exists with workflow '${existingState.workflowName}'. Cannot change to '${workflowName}'. Use reset_development() first to start with a new workflow.`;
8589
- logger9.error("Attempted workflow change on existing conversation", new Error(errorMessage), {
8530
+ logger8.error("Attempted workflow change on existing conversation", new Error(errorMessage), {
8590
8531
  existingWorkflow: existingState.workflowName,
8591
8532
  requestedWorkflow: workflowName,
8592
8533
  conversationId
8593
8534
  });
8594
8535
  throw new Error(errorMessage);
8595
8536
  }
8596
- logger9.debug("Conversation already exists, returning existing context", {
8537
+ logger8.debug("Conversation already exists, returning existing context", {
8597
8538
  conversationId
8598
8539
  });
8599
8540
  return {
@@ -8622,7 +8563,7 @@ var ConversationManager = class {
8622
8563
  * @param updates - Partial state updates to apply
8623
8564
  */
8624
8565
  async updateConversationState(conversationId, updates) {
8625
- logger9.debug("Updating conversation state", { conversationId, updates });
8566
+ logger8.debug("Updating conversation state", { conversationId, updates });
8626
8567
  const currentState = await this.database.getConversationState(conversationId);
8627
8568
  if (!currentState) {
8628
8569
  throw new Error(`Conversation state not found for ID: ${conversationId}`);
@@ -8633,7 +8574,7 @@ var ConversationManager = class {
8633
8574
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
8634
8575
  };
8635
8576
  await this.database.saveConversationState(updatedState);
8636
- logger9.info("Conversation state updated", {
8577
+ logger8.info("Conversation state updated", {
8637
8578
  conversationId,
8638
8579
  currentPhase: updatedState.currentPhase
8639
8580
  });
@@ -8646,7 +8587,7 @@ var ConversationManager = class {
8646
8587
  * @param gitBranch - Git branch name
8647
8588
  */
8648
8589
  async createNewConversationState(conversationId, projectPath, gitBranch, workflowName = "waterfall") {
8649
- logger9.info("Creating new conversation state", {
8590
+ logger8.info("Creating new conversation state", {
8650
8591
  conversationId,
8651
8592
  projectPath,
8652
8593
  gitBranch
@@ -8670,7 +8611,7 @@ var ConversationManager = class {
8670
8611
  updatedAt: timestamp2
8671
8612
  };
8672
8613
  await this.database.saveConversationState(newState);
8673
- logger9.info("New conversation state created", {
8614
+ logger8.info("New conversation state created", {
8674
8615
  conversationId,
8675
8616
  planFilePath,
8676
8617
  initialPhase
@@ -8713,7 +8654,7 @@ var ConversationManager = class {
8713
8654
  getGitBranch(projectPath) {
8714
8655
  try {
8715
8656
  if (!existsSync(`${projectPath}/.git`)) {
8716
- logger9.debug('Not a git repository, using "default" as branch name', {
8657
+ logger8.debug('Not a git repository, using "default" as branch name', {
8717
8658
  projectPath
8718
8659
  });
8719
8660
  return "default";
@@ -8724,10 +8665,10 @@ var ConversationManager = class {
8724
8665
  stdio: ["ignore", "pipe", "ignore"]
8725
8666
  // Suppress stderr
8726
8667
  }).trim();
8727
- logger9.debug("Detected git branch", { projectPath, branch });
8668
+ logger8.debug("Detected git branch", { projectPath, branch });
8728
8669
  return branch;
8729
8670
  } catch (_error) {
8730
- logger9.debug('Failed to get git branch, using "default" as branch name', {
8671
+ logger8.debug('Failed to get git branch, using "default" as branch name', {
8731
8672
  projectPath
8732
8673
  });
8733
8674
  return "default";
@@ -8741,13 +8682,13 @@ var ConversationManager = class {
8741
8682
  try {
8742
8683
  const interactions = await this.database.getInteractionsByConversationId(conversationId);
8743
8684
  const count = interactions.length;
8744
- logger9.debug("Checked interaction count for conversation", {
8685
+ logger8.debug("Checked interaction count for conversation", {
8745
8686
  conversationId,
8746
8687
  count
8747
8688
  });
8748
8689
  return count > 0;
8749
8690
  } catch (error) {
8750
- logger9.error("Failed to check interaction count", error, {
8691
+ logger8.error("Failed to check interaction count", error, {
8751
8692
  conversationId
8752
8693
  });
8753
8694
  return false;
@@ -8757,24 +8698,24 @@ var ConversationManager = class {
8757
8698
  * Reset conversation data (hybrid approach)
8758
8699
  */
8759
8700
  async resetConversation(confirm, reason) {
8760
- logger9.info("Starting conversation reset", { confirm, reason });
8701
+ logger8.info("Starting conversation reset", { confirm, reason });
8761
8702
  this.validateResetRequest(confirm);
8762
8703
  const context = await this.getConversationContext();
8763
8704
  const resetItems = [];
8764
8705
  try {
8765
8706
  await this.database.softDeleteInteractionLogs(context.conversationId);
8766
8707
  resetItems.push("interaction_logs");
8767
- logger9.debug("Interaction logs soft deleted");
8708
+ logger8.debug("Interaction logs soft deleted");
8768
8709
  await this.database.deleteConversationState(context.conversationId);
8769
8710
  resetItems.push("conversation_state");
8770
- logger9.debug("Conversation state hard deleted");
8711
+ logger8.debug("Conversation state hard deleted");
8771
8712
  const planManager = new PlanManager();
8772
8713
  await planManager.deletePlanFile(context.planFilePath);
8773
8714
  resetItems.push("plan_file");
8774
- logger9.debug("Plan file deleted");
8715
+ logger8.debug("Plan file deleted");
8775
8716
  await this.verifyResetCleanup(context.conversationId, context.planFilePath);
8776
8717
  const message = `Successfully reset conversation ${context.conversationId}. Reset items: ${resetItems.join(", ")}${reason ? `. Reason: ${reason}` : ""}`;
8777
- logger9.info("Conversation reset completed successfully", {
8718
+ logger8.info("Conversation reset completed successfully", {
8778
8719
  conversationId: context.conversationId,
8779
8720
  resetItems,
8780
8721
  reason
@@ -8786,7 +8727,7 @@ var ConversationManager = class {
8786
8727
  message
8787
8728
  };
8788
8729
  } catch (error) {
8789
- logger9.error("Failed to reset conversation", error, {
8730
+ logger8.error("Failed to reset conversation", error, {
8790
8731
  conversationId: context.conversationId,
8791
8732
  resetItems,
8792
8733
  reason
@@ -8806,7 +8747,7 @@ var ConversationManager = class {
8806
8747
  * Verify that reset cleanup was successful
8807
8748
  */
8808
8749
  async verifyResetCleanup(conversationId, planFilePath) {
8809
- logger9.debug("Verifying reset cleanup", { conversationId, planFilePath });
8750
+ logger8.debug("Verifying reset cleanup", { conversationId, planFilePath });
8810
8751
  try {
8811
8752
  const state = await this.database.getConversationState(conversationId);
8812
8753
  if (state) {
@@ -8817,9 +8758,9 @@ var ConversationManager = class {
8817
8758
  if (!isDeleted) {
8818
8759
  throw new Error("Plan file was not properly deleted");
8819
8760
  }
8820
- logger9.debug("Reset cleanup verification successful");
8761
+ logger8.debug("Reset cleanup verification successful");
8821
8762
  } catch (error) {
8822
- logger9.error("Reset cleanup verification failed", error);
8763
+ logger8.error("Reset cleanup verification failed", error);
8823
8764
  throw error;
8824
8765
  }
8825
8766
  }
@@ -8827,20 +8768,20 @@ var ConversationManager = class {
8827
8768
  * Clean up conversation data (used internally)
8828
8769
  */
8829
8770
  async cleanupConversationData(conversationId) {
8830
- logger9.debug("Cleaning up conversation data", { conversationId });
8771
+ logger8.debug("Cleaning up conversation data", { conversationId });
8831
8772
  try {
8832
8773
  await this.database.softDeleteInteractionLogs(conversationId);
8833
8774
  await this.database.deleteConversationState(conversationId);
8834
- logger9.debug("Conversation data cleanup completed", { conversationId });
8775
+ logger8.debug("Conversation data cleanup completed", { conversationId });
8835
8776
  } catch (error) {
8836
- logger9.error("Failed to cleanup conversation data", error, {
8777
+ logger8.error("Failed to cleanup conversation data", error, {
8837
8778
  conversationId
8838
8779
  });
8839
8780
  throw error;
8840
8781
  }
8841
8782
  }
8842
8783
  };
8843
- var logger10 = createLogger("TemplateManager");
8784
+ var logger9 = createLogger("TemplateManager");
8844
8785
  var TemplateManager = class {
8845
8786
  templatesPath;
8846
8787
  constructor() {
@@ -8869,13 +8810,13 @@ var TemplateManager = class {
8869
8810
  for (const strategy of strategies) {
8870
8811
  try {
8871
8812
  __require2("fs").accessSync(strategy);
8872
- logger10.debug("Using templates path", { path: strategy });
8813
+ logger9.debug("Using templates path", { path: strategy });
8873
8814
  return strategy;
8874
8815
  } catch (_error) {
8875
8816
  }
8876
8817
  }
8877
8818
  const fallback = strategies[0];
8878
- logger10.warn("No templates directory found, using fallback", {
8819
+ logger9.warn("No templates directory found, using fallback", {
8879
8820
  fallback,
8880
8821
  strategies
8881
8822
  });
@@ -8929,7 +8870,7 @@ var TemplateManager = class {
8929
8870
  const content = await readFile2(templateFilePath, "utf-8");
8930
8871
  return { content };
8931
8872
  } catch (error) {
8932
- logger10.error(`Failed to load template: ${type2}/${template}`, error);
8873
+ logger9.error(`Failed to load template: ${type2}/${template}`, error);
8933
8874
  throw new Error(`Template not found: ${type2}/${template}. Tried: ${templatePath} (directory) and ${templateFilePath} (file)`);
8934
8875
  }
8935
8876
  }
@@ -9010,26 +8951,28 @@ var TemplateManager = class {
9010
8951
  }
9011
8952
  templates.sort();
9012
8953
  } catch (error) {
9013
- logger10.warn(`Failed to scan templates for type: ${type2}`, {
8954
+ logger9.warn(`Failed to scan templates for type: ${type2}`, {
9014
8955
  typePath,
9015
8956
  error: error instanceof Error ? error.message : String(error)
9016
8957
  });
9017
8958
  }
9018
8959
  }
9019
- logger10.debug("Discovered available templates", result);
8960
+ logger9.debug("Discovered available templates", result);
9020
8961
  return result;
9021
8962
  } catch (error) {
9022
- logger10.error("Failed to discover templates", error);
8963
+ logger9.error("Failed to discover templates", error);
9023
8964
  return result;
9024
8965
  }
9025
8966
  }
9026
8967
  };
9027
- var logger11 = createLogger("ProjectDocsManager");
8968
+ var defaultLogger2 = createLogger("ProjectDocsManager");
9028
8969
  var ProjectDocsManager = class {
9029
8970
  templateManager;
9030
8971
  // Make public for access from other classes
9031
- constructor() {
8972
+ logger;
8973
+ constructor(logger24 = defaultLogger2) {
9032
8974
  this.templateManager = new TemplateManager();
8975
+ this.logger = logger24;
9033
8976
  }
9034
8977
  /**
9035
8978
  * Get project docs directory path
@@ -9200,7 +9143,7 @@ var ProjectDocsManager = class {
9200
9143
  } else {
9201
9144
  skipped.push("design.md");
9202
9145
  }
9203
- logger11.info("Project docs creation/linking completed", {
9146
+ this.logger.info("Project docs creation/linking completed", {
9204
9147
  created,
9205
9148
  linked,
9206
9149
  skipped,
@@ -9219,13 +9162,13 @@ var ProjectDocsManager = class {
9219
9162
  const targetDir = dirname4(targetPath);
9220
9163
  const relativePath = relative(targetDir, sourcePath);
9221
9164
  await symlink(relativePath, targetPath);
9222
- logger11.debug("Symlink created successfully", {
9165
+ this.logger.debug("Symlink created successfully", {
9223
9166
  sourcePath,
9224
9167
  targetPath,
9225
9168
  relativePath
9226
9169
  });
9227
9170
  } catch (error) {
9228
- logger11.error("Failed to create symlink", error, {
9171
+ this.logger.error("Failed to create symlink", error, {
9229
9172
  sourcePath,
9230
9173
  targetPath
9231
9174
  });
@@ -9239,14 +9182,14 @@ var ProjectDocsManager = class {
9239
9182
  try {
9240
9183
  const stats = await lstat(documentPath);
9241
9184
  await unlink(documentPath);
9242
- logger11.debug("Existing document removed", {
9185
+ this.logger.debug("Existing document removed", {
9243
9186
  documentPath,
9244
9187
  wasSymlink: stats.isSymbolicLink()
9245
9188
  });
9246
9189
  } catch (error) {
9247
9190
  const nodeError = error;
9248
9191
  if (error instanceof Error && "code" in nodeError && nodeError.code !== "ENOENT") {
9249
- logger11.debug("Failed to remove existing document", {
9192
+ this.logger.debug("Failed to remove existing document", {
9250
9193
  documentPath,
9251
9194
  error: nodeError.message
9252
9195
  });
@@ -9268,9 +9211,9 @@ var ProjectDocsManager = class {
9268
9211
  await writeFile2(filePath, file.content.toString());
9269
9212
  }
9270
9213
  }
9271
- logger11.debug(`Created ${type2} document`, { documentPath, template });
9214
+ this.logger.debug(`Created ${type2} document`, { documentPath, template });
9272
9215
  } catch (error) {
9273
- logger11.error(`Failed to create ${type2} document`, error, {
9216
+ this.logger.error(`Failed to create ${type2} document`, error, {
9274
9217
  documentPath,
9275
9218
  template
9276
9219
  });
@@ -9337,8 +9280,8 @@ var ProjectDocsManager = class {
9337
9280
  }
9338
9281
  }
9339
9282
  };
9340
- var logger12 = createLogger("FileDetectionManager");
9341
- var logger13 = createLogger("GitManager");
9283
+ var logger10 = createLogger("FileDetectionManager");
9284
+ var logger11 = createLogger("GitManager");
9342
9285
  var GitManager = class {
9343
9286
  /**
9344
9287
  * Check if a directory is a git repository
@@ -9352,7 +9295,7 @@ var GitManager = class {
9352
9295
  static getCurrentBranch(projectPath) {
9353
9296
  try {
9354
9297
  if (!this.isGitRepository(projectPath)) {
9355
- logger13.debug('Not a git repository, using "default" as branch name', {
9298
+ logger11.debug('Not a git repository, using "default" as branch name', {
9356
9299
  projectPath
9357
9300
  });
9358
9301
  return "default";
@@ -9362,10 +9305,10 @@ var GitManager = class {
9362
9305
  encoding: "utf-8",
9363
9306
  stdio: ["ignore", "pipe", "ignore"]
9364
9307
  }).trim();
9365
- logger13.debug("Detected git branch", { projectPath, branch });
9308
+ logger11.debug("Detected git branch", { projectPath, branch });
9366
9309
  return branch;
9367
9310
  } catch (_error) {
9368
- logger13.debug('Failed to get git branch, using "default" as branch name', {
9311
+ logger11.debug('Failed to get git branch, using "default" as branch name', {
9369
9312
  projectPath
9370
9313
  });
9371
9314
  return "default";
@@ -9386,7 +9329,7 @@ var GitManager = class {
9386
9329
  }).trim();
9387
9330
  return hash;
9388
9331
  } catch (error) {
9389
- logger13.debug("Failed to get current commit hash", { projectPath, error });
9332
+ logger11.debug("Failed to get current commit hash", { projectPath, error });
9390
9333
  return null;
9391
9334
  }
9392
9335
  }
@@ -9396,7 +9339,7 @@ var GitManager = class {
9396
9339
  static createCommit(message, projectPath) {
9397
9340
  try {
9398
9341
  if (!this.isGitRepository(projectPath)) {
9399
- logger13.debug("Not a git repository, skipping commit", { projectPath });
9342
+ logger11.debug("Not a git repository, skipping commit", { projectPath });
9400
9343
  return false;
9401
9344
  }
9402
9345
  execSync2("git add .", {
@@ -9409,10 +9352,10 @@ var GitManager = class {
9409
9352
  encoding: "utf-8",
9410
9353
  stdio: ["ignore", "pipe", "ignore"]
9411
9354
  });
9412
- logger13.debug("Created commit successfully", { projectPath, message });
9355
+ logger11.debug("Created commit successfully", { projectPath, message });
9413
9356
  return true;
9414
9357
  } catch (error) {
9415
- logger13.debug("Failed to create commit", {
9358
+ logger11.debug("Failed to create commit", {
9416
9359
  projectPath,
9417
9360
  message,
9418
9361
  error: error instanceof Error ? error.message : String(error)
@@ -9426,7 +9369,7 @@ var GitManager = class {
9426
9369
  static hasUncommittedChanges(projectPath) {
9427
9370
  try {
9428
9371
  if (!this.isGitRepository(projectPath)) {
9429
- logger13.debug("Not a git repository, no uncommitted changes", {
9372
+ logger11.debug("Not a git repository, no uncommitted changes", {
9430
9373
  projectPath
9431
9374
  });
9432
9375
  return false;
@@ -9437,13 +9380,13 @@ var GitManager = class {
9437
9380
  stdio: ["ignore", "pipe", "ignore"]
9438
9381
  }).trim();
9439
9382
  const hasChanges = status.length > 0;
9440
- logger13.debug("Checked for uncommitted changes", {
9383
+ logger11.debug("Checked for uncommitted changes", {
9441
9384
  projectPath,
9442
9385
  hasChanges
9443
9386
  });
9444
9387
  return hasChanges;
9445
9388
  } catch (error) {
9446
- logger13.debug("Failed to check for uncommitted changes", {
9389
+ logger11.debug("Failed to check for uncommitted changes", {
9447
9390
  projectPath,
9448
9391
  error: error instanceof Error ? error.message : String(error)
9449
9392
  });
@@ -9451,7 +9394,7 @@ var GitManager = class {
9451
9394
  }
9452
9395
  }
9453
9396
  };
9454
- var logger14 = createLogger("TaskBackend");
9397
+ var defaultLogger3 = createLogger("TaskBackend");
9455
9398
  var TaskBackendManager = class _TaskBackendManager {
9456
9399
  /**
9457
9400
  * Detect and validate the requested task backend
@@ -9463,18 +9406,19 @@ var TaskBackendManager = class _TaskBackendManager {
9463
9406
  * When TASK_BACKEND is explicitly set:
9464
9407
  * - Uses the specified backend (markdown or beads)
9465
9408
  * - For beads, validates availability and provides setup instructions if not available
9409
+ *
9466
9410
  */
9467
- static detectTaskBackend() {
9411
+ static detectTaskBackend(logger24 = defaultLogger3) {
9468
9412
  const envBackend = process.env["TASK_BACKEND"]?.toLowerCase().trim();
9469
9413
  if (envBackend && !["markdown", "beads"].includes(envBackend)) {
9470
- logger14.debug("Invalid TASK_BACKEND value, treating as not set", {
9414
+ logger24.debug("Invalid TASK_BACKEND value, treating as not set", {
9471
9415
  envBackend
9472
9416
  });
9473
9417
  }
9474
9418
  if (!envBackend || !["markdown", "beads"].includes(envBackend)) {
9475
- const beadsAvailable2 = _TaskBackendManager.checkBeadsAvailability();
9419
+ const beadsAvailable2 = _TaskBackendManager.checkBeadsAvailability(logger24);
9476
9420
  if (beadsAvailable2.isAvailable) {
9477
- logger14.info("Auto-detected beads backend (bd command available)", {
9421
+ logger24.debug("Auto-detected beads backend (bd command available)", {
9478
9422
  reason: "TASK_BACKEND not set, bd command found"
9479
9423
  });
9480
9424
  return {
@@ -9482,7 +9426,7 @@ var TaskBackendManager = class _TaskBackendManager {
9482
9426
  isAvailable: true
9483
9427
  };
9484
9428
  }
9485
- logger14.debug("Using markdown backend (bd command not available)", {
9429
+ logger24.debug("Using markdown backend (bd command not available)", {
9486
9430
  reason: "TASK_BACKEND not set, bd command not found"
9487
9431
  });
9488
9432
  return {
@@ -9492,15 +9436,15 @@ var TaskBackendManager = class _TaskBackendManager {
9492
9436
  }
9493
9437
  const backend = envBackend;
9494
9438
  if (backend === "markdown") {
9495
- logger14.debug("Using explicitly configured markdown backend");
9439
+ logger24.debug("Using explicitly configured markdown backend");
9496
9440
  return {
9497
9441
  backend: "markdown",
9498
9442
  isAvailable: true
9499
9443
  };
9500
9444
  }
9501
- const beadsAvailable = _TaskBackendManager.checkBeadsAvailability();
9445
+ const beadsAvailable = _TaskBackendManager.checkBeadsAvailability(logger24);
9502
9446
  if (beadsAvailable.isAvailable) {
9503
- logger14.debug("Using explicitly configured beads backend");
9447
+ logger24.debug("Using explicitly configured beads backend");
9504
9448
  return {
9505
9449
  backend: "beads",
9506
9450
  isAvailable: true
@@ -9515,14 +9459,14 @@ var TaskBackendManager = class _TaskBackendManager {
9515
9459
  /**
9516
9460
  * Check if beads command is available and functional
9517
9461
  */
9518
- static checkBeadsAvailability() {
9462
+ static checkBeadsAvailability(logger24 = defaultLogger3) {
9519
9463
  try {
9520
9464
  const output = execSync3("bd --version", {
9521
9465
  encoding: "utf-8",
9522
9466
  stdio: ["ignore", "pipe", "pipe"],
9523
9467
  timeout: 5e3
9524
9468
  });
9525
- logger14.debug("Beads command available", { version: output.trim() });
9469
+ logger24.debug("Beads command available", { version: output.trim() });
9526
9470
  return { isAvailable: true };
9527
9471
  } catch (error) {
9528
9472
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -9538,7 +9482,7 @@ var TaskBackendManager = class _TaskBackendManager {
9538
9482
  errorMessage: "Beads command (bd) timed out. Check if beads is properly installed and configured."
9539
9483
  };
9540
9484
  }
9541
- logger14.warn("Beads availability check failed", { errorMessage });
9485
+ logger24.warn("Beads availability check failed", { errorMessage });
9542
9486
  return {
9543
9487
  isAvailable: false,
9544
9488
  errorMessage: `Beads command (bd) check failed: ${errorMessage}`
@@ -9591,9 +9535,10 @@ export TASK_BACKEND=markdown
9591
9535
  }
9592
9536
  /**
9593
9537
  * Validate task backend configuration and throw error if invalid
9538
+ *
9594
9539
  */
9595
- static validateTaskBackend() {
9596
- const config = this.detectTaskBackend();
9540
+ static validateTaskBackend(logger24 = defaultLogger3) {
9541
+ const config = this.detectTaskBackend(logger24);
9597
9542
  if (!config.isAvailable) {
9598
9543
  const setupInstructions = config.backend === "beads" ? this.getBeadsSetupInstructions() : "Task backend validation failed";
9599
9544
  throw new Error(`Task backend '${config.backend}' is not available.
@@ -9602,18 +9547,20 @@ ${config.errorMessage || ""}
9602
9547
 
9603
9548
  ${setupInstructions}`);
9604
9549
  }
9605
- logger14.info("Task backend validated successfully", {
9550
+ logger24.info("Task backend validated successfully", {
9606
9551
  backend: config.backend,
9607
9552
  available: config.isAvailable
9608
9553
  });
9609
9554
  return config;
9610
9555
  }
9611
9556
  };
9612
- var logger15 = createLogger("BeadsIntegration");
9557
+ var defaultLogger4 = createLogger("BeadsIntegration");
9613
9558
  var BeadsIntegration = class {
9614
9559
  projectPath;
9615
- constructor(projectPath) {
9560
+ logger;
9561
+ constructor(projectPath, logger24 = defaultLogger4) {
9616
9562
  this.projectPath = projectPath;
9563
+ this.logger = logger24;
9617
9564
  }
9618
9565
  /**
9619
9566
  * Ensure beads is initialized in the project directory
@@ -9629,7 +9576,7 @@ var BeadsIntegration = class {
9629
9576
  } catch (error) {
9630
9577
  const errorMessage = error instanceof Error ? error.message : String(error);
9631
9578
  if (errorMessage.includes("not initialized") || errorMessage.includes("no database") || errorMessage.includes("init")) {
9632
- logger15.info("Beads not initialized, running bd init --no-db", {
9579
+ this.logger.info("Beads not initialized, running bd init --no-db", {
9633
9580
  projectPath: this.projectPath
9634
9581
  });
9635
9582
  try {
@@ -9638,12 +9585,12 @@ var BeadsIntegration = class {
9638
9585
  encoding: "utf-8",
9639
9586
  stdio: ["ignore", "pipe", "pipe"]
9640
9587
  });
9641
- logger15.info("Successfully initialized beads in project", {
9588
+ this.logger.info("Successfully initialized beads in project", {
9642
9589
  projectPath: this.projectPath
9643
9590
  });
9644
9591
  } catch (initError) {
9645
9592
  const initErrorMessage = initError instanceof Error ? initError.message : String(initError);
9646
- logger15.error("Failed to initialize beads", initError instanceof Error ? initError : new Error(initErrorMessage), { projectPath: this.projectPath });
9593
+ this.logger.error("Failed to initialize beads", initError instanceof Error ? initError : new Error(initErrorMessage), { projectPath: this.projectPath });
9647
9594
  throw new Error(`Failed to initialize beads: ${initErrorMessage}`);
9648
9595
  }
9649
9596
  } else {
@@ -9661,7 +9608,7 @@ var BeadsIntegration = class {
9661
9608
  const epicDescription = description || `Responsible vibe engineering session using ${workflowName} workflow for ${projectName}`;
9662
9609
  const priority = 2;
9663
9610
  const command = `bd create "${epicTitle}" --description "${epicDescription}" --priority ${priority}`;
9664
- logger15.debug("Creating beads project epic", {
9611
+ this.logger.debug("Creating beads project epic", {
9665
9612
  command,
9666
9613
  projectName,
9667
9614
  workflowName,
@@ -9675,7 +9622,7 @@ var BeadsIntegration = class {
9675
9622
  });
9676
9623
  const match = output.match(/✓ Created issue: ([\w\d.-]+)/) || output.match(/Created issue: ([\w\d.-]+)/) || output.match(/Created (bd-[\w\d.]+)/);
9677
9624
  if (!match) {
9678
- logger15.warn("Failed to extract task ID from beads output", {
9625
+ this.logger.warn("Failed to extract task ID from beads output", {
9679
9626
  command: `bd create "${epicTitle}" --description "${epicDescription}" --priority 2`,
9680
9627
  output: output.slice(0, 200)
9681
9628
  // Truncated for logging
@@ -9683,7 +9630,7 @@ var BeadsIntegration = class {
9683
9630
  throw new Error(`Failed to extract task ID from beads output: ${output.slice(0, 100)}...`);
9684
9631
  }
9685
9632
  const epicId = match[1] || "";
9686
- logger15.info("Created beads project epic", {
9633
+ this.logger.info("Created beads project epic", {
9687
9634
  epicId,
9688
9635
  epicTitle,
9689
9636
  projectPath: this.projectPath
@@ -9697,10 +9644,10 @@ var BeadsIntegration = class {
9697
9644
  workflowName,
9698
9645
  projectPath: this.projectPath
9699
9646
  };
9700
- logger15.error("Failed to create beads project epic", error instanceof Error ? error : new Error(errorMessage), commandInfo);
9647
+ this.logger.error("Failed to create beads project epic", error instanceof Error ? error : new Error(errorMessage), commandInfo);
9701
9648
  const execError = error;
9702
9649
  if (execError?.stderr) {
9703
- logger15.error("Beads command stderr output", new Error("Command stderr"), {
9650
+ this.logger.error("Beads command stderr output", new Error("Command stderr"), {
9704
9651
  stderr: execError.stderr.toString(),
9705
9652
  ...commandInfo
9706
9653
  });
@@ -9716,12 +9663,12 @@ var BeadsIntegration = class {
9716
9663
  const phaseTasks = [];
9717
9664
  const phaseNames = Object.keys(phases);
9718
9665
  for (const phase of phaseNames) {
9719
- const phaseTitle = `${this.capitalizePhase(phase)}`;
9666
+ const phaseTitle = capitalizePhase(phase);
9720
9667
  const priority = 3;
9721
9668
  const stateDefinition = phases[phase];
9722
9669
  const description = (stateDefinition?.default_instructions || `${workflowName} workflow ${phase} phase tasks`).replace(/"/g, '\\"').replace(/\n/g, " ").replace(/\r/g, "").trim();
9723
9670
  const command = `bd create "${phaseTitle}" --description "${description}" --parent ${epicId} --priority ${priority}`;
9724
- logger15.debug("Creating beads phase task", {
9671
+ this.logger.debug("Creating beads phase task", {
9725
9672
  command,
9726
9673
  phase,
9727
9674
  epicId,
@@ -9735,7 +9682,7 @@ var BeadsIntegration = class {
9735
9682
  });
9736
9683
  const match = output.match(/✓ Created issue: ([\w\d.-]+)/) || output.match(/Created issue: ([\w\d.-]+)/) || output.match(/Created (bd-[\w\d.]+)/);
9737
9684
  if (!match) {
9738
- logger15.warn("Failed to extract phase task ID from beads output", {
9685
+ this.logger.warn("Failed to extract phase task ID from beads output", {
9739
9686
  command,
9740
9687
  output: output.slice(0, 200)
9741
9688
  // Truncated for logging
@@ -9748,7 +9695,7 @@ var BeadsIntegration = class {
9748
9695
  phaseName: phaseTitle,
9749
9696
  taskId: phaseTaskId
9750
9697
  });
9751
- logger15.debug("Created beads phase task", {
9698
+ this.logger.debug("Created beads phase task", {
9752
9699
  phase,
9753
9700
  phaseTaskId,
9754
9701
  epicId,
@@ -9762,10 +9709,10 @@ var BeadsIntegration = class {
9762
9709
  epicId,
9763
9710
  projectPath: this.projectPath
9764
9711
  };
9765
- logger15.error("Failed to create beads phase task", error instanceof Error ? error : new Error(errorMessage), commandInfo);
9712
+ this.logger.error("Failed to create beads phase task", error instanceof Error ? error : new Error(errorMessage), commandInfo);
9766
9713
  const execError = error;
9767
9714
  if (execError?.stderr) {
9768
- logger15.error("Beads phase command stderr output", new Error("Command stderr"), {
9715
+ this.logger.error("Beads phase command stderr output", new Error("Command stderr"), {
9769
9716
  stderr: execError.stderr.toString(),
9770
9717
  ...commandInfo
9771
9718
  });
@@ -9773,7 +9720,7 @@ var BeadsIntegration = class {
9773
9720
  throw new Error(`Failed to create beads phase task for ${phase}: ${errorMessage}`);
9774
9721
  }
9775
9722
  }
9776
- logger15.info("Created all beads phase tasks", {
9723
+ this.logger.info("Created all beads phase tasks", {
9777
9724
  count: phaseTasks.length,
9778
9725
  epicId,
9779
9726
  projectPath: this.projectPath
@@ -9786,13 +9733,13 @@ var BeadsIntegration = class {
9786
9733
  */
9787
9734
  async createPhaseDependencies(phaseTasks) {
9788
9735
  if (phaseTasks.length < 2) {
9789
- logger15.debug("Skipping phase dependencies - less than 2 phases", {
9736
+ this.logger.debug("Skipping phase dependencies - less than 2 phases", {
9790
9737
  phaseCount: phaseTasks.length,
9791
9738
  projectPath: this.projectPath
9792
9739
  });
9793
9740
  return;
9794
9741
  }
9795
- logger15.info("Creating sequential phase dependencies", {
9742
+ this.logger.info("Creating sequential phase dependencies", {
9796
9743
  phaseCount: phaseTasks.length,
9797
9744
  projectPath: this.projectPath
9798
9745
  });
@@ -9801,7 +9748,7 @@ var BeadsIntegration = class {
9801
9748
  const currentPhase = phaseTasks[i2];
9802
9749
  const nextPhase = phaseTasks[i2 + 1];
9803
9750
  if (!currentPhase || !nextPhase) {
9804
- logger15.warn("Skipping phase dependency - missing phase data", {
9751
+ this.logger.warn("Skipping phase dependency - missing phase data", {
9805
9752
  currentPhaseIndex: i2,
9806
9753
  nextPhaseIndex: i2 + 1,
9807
9754
  totalPhases: phaseTasks.length,
@@ -9815,7 +9762,7 @@ var BeadsIntegration = class {
9815
9762
  continue;
9816
9763
  }
9817
9764
  const command = `bd dep ${currentPhase.taskId} --blocks ${nextPhase.taskId}`;
9818
- logger15.debug("Creating phase dependency", {
9765
+ this.logger.debug("Creating phase dependency", {
9819
9766
  command,
9820
9767
  currentPhase: currentPhase.phaseName,
9821
9768
  nextPhase: nextPhase.phaseName,
@@ -9829,14 +9776,14 @@ var BeadsIntegration = class {
9829
9776
  encoding: "utf-8",
9830
9777
  stdio: ["ignore", "pipe", "pipe"]
9831
9778
  });
9832
- logger15.debug("Successfully created phase dependency", {
9779
+ this.logger.debug("Successfully created phase dependency", {
9833
9780
  currentPhase: currentPhase.phaseName,
9834
9781
  nextPhase: nextPhase.phaseName,
9835
9782
  projectPath: this.projectPath
9836
9783
  });
9837
9784
  } catch (error) {
9838
9785
  const errorMessage = error instanceof Error ? error.message : String(error);
9839
- logger15.warn("Failed to create phase dependency - continuing anyway", {
9786
+ this.logger.warn("Failed to create phase dependency - continuing anyway", {
9840
9787
  error: errorMessage,
9841
9788
  command,
9842
9789
  currentPhase: currentPhase.phaseName,
@@ -9845,7 +9792,7 @@ var BeadsIntegration = class {
9845
9792
  });
9846
9793
  const execError = error;
9847
9794
  if (execError?.stderr) {
9848
- logger15.debug("Beads dependency command stderr", {
9795
+ this.logger.debug("Beads dependency command stderr", {
9849
9796
  stderr: execError.stderr.toString(),
9850
9797
  command,
9851
9798
  projectPath: this.projectPath
@@ -9859,25 +9806,19 @@ var BeadsIntegration = class {
9859
9806
  }
9860
9807
  }
9861
9808
  if (failedDependencies.length > 0) {
9862
- logger15.warn("Some phase dependencies could not be created - app continues without these dependencies", {
9809
+ this.logger.warn("Some phase dependencies could not be created - app continues without these dependencies", {
9863
9810
  failedCount: failedDependencies.length,
9864
9811
  failedDependencies,
9865
9812
  projectPath: this.projectPath
9866
9813
  });
9867
9814
  }
9868
- logger15.info("Completed phase dependency creation", {
9815
+ this.logger.info("Completed phase dependency creation", {
9869
9816
  dependencyCount: phaseTasks.length - 1,
9870
9817
  successCount: phaseTasks.length - 1 - failedDependencies.length,
9871
9818
  failedCount: failedDependencies.length,
9872
9819
  projectPath: this.projectPath
9873
9820
  });
9874
9821
  }
9875
- /**
9876
- * Capitalize phase name for display
9877
- */
9878
- capitalizePhase(phase) {
9879
- return phase.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
9880
- }
9881
9822
  /**
9882
9823
  * Validate parameters for epic creation
9883
9824
  */
@@ -9921,11 +9862,13 @@ var BeadsIntegration = class {
9921
9862
  }
9922
9863
  }
9923
9864
  };
9924
- var logger16 = createLogger("BeadsStateManager");
9865
+ var defaultLogger5 = createLogger("BeadsStateManager");
9925
9866
  var BeadsStateManager = class {
9926
9867
  projectPath;
9927
- constructor(projectPath) {
9868
+ logger;
9869
+ constructor(projectPath, logger24 = defaultLogger5) {
9928
9870
  this.projectPath = projectPath;
9871
+ this.logger = logger24;
9929
9872
  }
9930
9873
  /**
9931
9874
  * Get the path to the beads state file for a conversation
@@ -9946,7 +9889,7 @@ var BeadsStateManager = class {
9946
9889
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
9947
9890
  };
9948
9891
  await this.saveState(state);
9949
- logger16.info("Created beads conversation state", {
9892
+ this.logger.info("Created beads conversation state", {
9950
9893
  conversationId,
9951
9894
  epicId,
9952
9895
  phaseCount: phaseTasks.length,
@@ -9963,7 +9906,7 @@ var BeadsStateManager = class {
9963
9906
  await access5(statePath);
9964
9907
  const content = await readFile3(statePath, "utf-8");
9965
9908
  const state = JSON.parse(content);
9966
- logger16.debug("Retrieved beads conversation state", {
9909
+ this.logger.debug("Retrieved beads conversation state", {
9967
9910
  conversationId,
9968
9911
  epicId: state.epicId,
9969
9912
  phaseCount: state.phaseTasks.length,
@@ -9972,14 +9915,14 @@ var BeadsStateManager = class {
9972
9915
  return state;
9973
9916
  } catch (error) {
9974
9917
  if (error.code === "ENOENT") {
9975
- logger16.debug("No beads state found for conversation", {
9918
+ this.logger.debug("No beads state found for conversation", {
9976
9919
  conversationId,
9977
9920
  projectPath: this.projectPath
9978
9921
  });
9979
9922
  return null;
9980
9923
  }
9981
9924
  const errorMessage = error instanceof Error ? error.message : String(error);
9982
- logger16.warn("Failed to read beads state file", {
9925
+ this.logger.warn("Failed to read beads state file", {
9983
9926
  error: errorMessage,
9984
9927
  conversationId,
9985
9928
  statePath,
@@ -9998,7 +9941,7 @@ var BeadsStateManager = class {
9998
9941
  }
9999
9942
  const phaseTask = state.phaseTasks.find((task) => task.phaseId === phase);
10000
9943
  if (phaseTask) {
10001
- logger16.debug("Found phase task ID", {
9944
+ this.logger.debug("Found phase task ID", {
10002
9945
  conversationId,
10003
9946
  phase,
10004
9947
  taskId: phaseTask.taskId,
@@ -10006,7 +9949,7 @@ var BeadsStateManager = class {
10006
9949
  });
10007
9950
  return phaseTask.taskId;
10008
9951
  }
10009
- logger16.debug("No task ID found for phase", {
9952
+ this.logger.debug("No task ID found for phase", {
10010
9953
  conversationId,
10011
9954
  phase,
10012
9955
  availablePhases: state.phaseTasks.map((t) => t.phaseId),
@@ -10020,7 +9963,7 @@ var BeadsStateManager = class {
10020
9963
  async updateState(conversationId, updates) {
10021
9964
  const existingState = await this.getState(conversationId);
10022
9965
  if (!existingState) {
10023
- logger16.warn("Cannot update non-existent beads state", {
9966
+ this.logger.warn("Cannot update non-existent beads state", {
10024
9967
  conversationId,
10025
9968
  projectPath: this.projectPath
10026
9969
  });
@@ -10034,7 +9977,7 @@ var BeadsStateManager = class {
10034
9977
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
10035
9978
  };
10036
9979
  await this.saveState(updatedState);
10037
- logger16.info("Updated beads conversation state", {
9980
+ this.logger.info("Updated beads conversation state", {
10038
9981
  conversationId,
10039
9982
  updatedFields: Object.keys(updates),
10040
9983
  projectPath: this.projectPath
@@ -10049,21 +9992,21 @@ var BeadsStateManager = class {
10049
9992
  try {
10050
9993
  await access5(statePath);
10051
9994
  await writeFile3(statePath + ".backup", await readFile3(statePath));
10052
- logger16.info("Cleaned up beads conversation state", {
9995
+ this.logger.info("Cleaned up beads conversation state", {
10053
9996
  conversationId,
10054
9997
  statePath,
10055
9998
  projectPath: this.projectPath
10056
9999
  });
10057
10000
  } catch (error) {
10058
10001
  if (error.code === "ENOENT") {
10059
- logger16.debug("No beads state to clean up", {
10002
+ this.logger.debug("No beads state to clean up", {
10060
10003
  conversationId,
10061
10004
  projectPath: this.projectPath
10062
10005
  });
10063
10006
  return;
10064
10007
  }
10065
10008
  const errorMessage = error instanceof Error ? error.message : String(error);
10066
- logger16.warn("Failed to clean up beads state", {
10009
+ this.logger.warn("Failed to clean up beads state", {
10067
10010
  error: errorMessage,
10068
10011
  conversationId,
10069
10012
  statePath,
@@ -10093,7 +10036,7 @@ var BeadsStateManager = class {
10093
10036
  await mkdir3(stateDir, { recursive: true });
10094
10037
  const content = JSON.stringify(state, null, 2);
10095
10038
  await writeFile3(statePath, content, "utf-8");
10096
- logger16.debug("Saved beads state to file", {
10039
+ this.logger.debug("Saved beads state to file", {
10097
10040
  conversationId: state.conversationId,
10098
10041
  statePath,
10099
10042
  fileSize: content.length,
@@ -10101,7 +10044,7 @@ var BeadsStateManager = class {
10101
10044
  });
10102
10045
  } catch (error) {
10103
10046
  const errorMessage = error instanceof Error ? error.message : String(error);
10104
- logger16.error("Failed to save beads state", error instanceof Error ? error : new Error(errorMessage), {
10047
+ this.logger.error("Failed to save beads state", error instanceof Error ? error : new Error(errorMessage), {
10105
10048
  conversationId: state.conversationId,
10106
10049
  statePath,
10107
10050
  projectPath: this.projectPath
@@ -10110,7 +10053,7 @@ var BeadsStateManager = class {
10110
10053
  }
10111
10054
  }
10112
10055
  };
10113
- var logger17 = createLogger("InteractionLogger");
10056
+ var logger12 = createLogger("InteractionLogger");
10114
10057
  var InteractionLogger = class {
10115
10058
  database;
10116
10059
  /**
@@ -10120,7 +10063,7 @@ var InteractionLogger = class {
10120
10063
  */
10121
10064
  constructor(database) {
10122
10065
  this.database = database;
10123
- logger17.debug("InteractionLogger initialized");
10066
+ logger12.debug("InteractionLogger initialized");
10124
10067
  }
10125
10068
  /**
10126
10069
  * Log an interaction with a tool
@@ -10133,7 +10076,7 @@ var InteractionLogger = class {
10133
10076
  * @returns Promise that resolves when the log is saved
10134
10077
  */
10135
10078
  async logInteraction(conversationId, toolName, inputParams, responseData, currentPhase) {
10136
- logger17.debug("Logging interaction", {
10079
+ logger12.debug("Logging interaction", {
10137
10080
  conversationId,
10138
10081
  toolName,
10139
10082
  currentPhase
@@ -10149,13 +10092,13 @@ var InteractionLogger = class {
10149
10092
  timestamp: timestamp2
10150
10093
  };
10151
10094
  await this.database.logInteraction(log);
10152
- logger17.info("Interaction logged successfully", {
10095
+ logger12.info("Interaction logged successfully", {
10153
10096
  conversationId,
10154
10097
  toolName,
10155
10098
  timestamp: timestamp2
10156
10099
  });
10157
10100
  } catch (error) {
10158
- logger17.error("Failed to log interaction", error, {
10101
+ logger12.error("Failed to log interaction", error, {
10159
10102
  conversationId,
10160
10103
  toolName
10161
10104
  });
@@ -10168,16 +10111,16 @@ var InteractionLogger = class {
10168
10111
  * @returns Promise that resolves to an array of interaction logs
10169
10112
  */
10170
10113
  async getInteractionsByConversationId(conversationId) {
10171
- logger17.debug("Getting interactions by conversation ID", { conversationId });
10114
+ logger12.debug("Getting interactions by conversation ID", { conversationId });
10172
10115
  try {
10173
10116
  const logs = await this.database.getInteractionsByConversationId(conversationId);
10174
- logger17.info("Retrieved interaction logs", {
10117
+ logger12.info("Retrieved interaction logs", {
10175
10118
  conversationId,
10176
10119
  count: logs.length
10177
10120
  });
10178
10121
  return logs;
10179
10122
  } catch (error) {
10180
- logger17.error("Failed to get interaction logs", error, {
10123
+ logger12.error("Failed to get interaction logs", error, {
10181
10124
  conversationId
10182
10125
  });
10183
10126
  throw error;
@@ -10186,11 +10129,11 @@ var InteractionLogger = class {
10186
10129
  };
10187
10130
  var InstructionGenerator = class {
10188
10131
  projectDocsManager;
10189
- constructor(_planManager) {
10190
- this.projectDocsManager = new ProjectDocsManager();
10132
+ constructor(logger24 = createLogger("InstructionGenerator")) {
10133
+ this.projectDocsManager = new ProjectDocsManager(logger24);
10191
10134
  }
10192
10135
  /**
10193
- * Set the state machine definition for dynamic instruction generation
10136
+ * No-op: all phase context is provided per-call via InstructionContext.
10194
10137
  */
10195
10138
  setStateMachine(_stateMachine) {
10196
10139
  return;
@@ -10203,7 +10146,6 @@ var InstructionGenerator = class {
10203
10146
  const enhancedInstructions = await this.enhanceInstructions(substitutedInstructions, context);
10204
10147
  return {
10205
10148
  instructions: enhancedInstructions,
10206
- planFileGuidance: "Task management guidance is now included in main instructions",
10207
10149
  metadata: {
10208
10150
  phase: context.phase,
10209
10151
  planFilePath: context.conversationContext.planFilePath,
@@ -10234,41 +10176,34 @@ var InstructionGenerator = class {
10234
10176
  * Enhance base instructions with context-specific information
10235
10177
  */
10236
10178
  async enhanceInstructions(baseInstructions, context) {
10237
- const { phase, conversationContext, planFileExists } = context;
10238
- const phaseName = this.capitalizePhase(phase);
10179
+ const { phase, conversationContext, allowedFilePatterns } = context;
10180
+ const phaseName = capitalizePhase(phase);
10239
10181
  let workflowSection = `---
10240
- **Workflow Continuity:**
10241
- Maintain \`${conversationContext.planFilePath}\`:
10242
- - Work through tasks in the "${phaseName}" section; Focus on those tasks!
10243
- - Add newly discovered tasks; log decisions in "Key Decisions"
10244
- - DO NOT maintain tasks in other tools or documents than explicitly stated in this plan file!`;
10245
- if (!planFileExists) {
10246
- workflowSection += "\n- Note: plan file will be created on first update";
10247
- }
10248
- workflowSection += "\n\nCall `whats_next()` after each user message.";
10182
+ **Read \`${conversationContext.planFilePath}\`** for context.
10183
+ - Focus on "${phaseName}" tasks, log decisions in "Key Decisions"
10184
+ - Do NOT use other task/todo tools - use only the plan file for task tracking`;
10185
+ if (allowedFilePatterns && allowedFilePatterns.length > 0 && !allowedFilePatterns.includes("**/*") && !allowedFilePatterns.includes("*")) {
10186
+ workflowSection += `
10187
+ - Files allowed: \`${allowedFilePatterns.join("`, `")}\``;
10188
+ }
10189
+ workflowSection += "\n\nCall `whats_next()` after user messages.";
10249
10190
  return `## ${phaseName} Phase
10250
10191
 
10251
10192
  ${baseInstructions}
10252
10193
 
10253
10194
  ${workflowSection}`;
10254
10195
  }
10255
- /**
10256
- * Capitalize phase name for display
10257
- */
10258
- capitalizePhase(phase) {
10259
- return phase.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
10260
- }
10261
10196
  };
10262
- var logger18 = createLogger("SystemPromptGenerator");
10197
+ var logger13 = createLogger("SystemPromptGenerator");
10263
10198
  function generateSystemPrompt(stateMachine) {
10264
- logger18.debug("Generating system prompt from state machine definition", {
10199
+ logger13.debug("Generating system prompt from state machine definition", {
10265
10200
  stateMachineName: stateMachine.name,
10266
10201
  phaseCount: Object.keys(stateMachine.states).length
10267
10202
  });
10268
10203
  return generateSimpleSystemPrompt(stateMachine);
10269
10204
  }
10270
10205
  function generateSimpleSystemPrompt(_stateMachine) {
10271
- logger18.debug("Generating system prompt");
10206
+ logger13.debug("Generating system prompt");
10272
10207
  const systemPrompt = `
10273
10208
  You are an AI assistant that helps users develop software features using the workflows server.
10274
10209
 
@@ -10279,17 +10214,18 @@ Each tool call returns a JSON response with an "instructions" field. Follow thes
10279
10214
  Use the development plan which you will retrieve via whats_next() to record important insights and decisions as per the structure of the plan.
10280
10215
 
10281
10216
  Do not use your own task management tools.`;
10282
- logger18.info("System prompt generated successfully", {
10217
+ logger13.info("System prompt generated successfully", {
10283
10218
  promptLength: systemPrompt.length
10284
10219
  });
10285
10220
  return systemPrompt;
10286
10221
  }
10287
- var logger19 = createLogger("ServerHelpers");
10288
- function normalizeProjectPath(projectPath) {
10222
+ var defaultLogger6 = createLogger("ServerHelpers");
10223
+ function normalizeProjectPath(projectPath, logger24) {
10224
+ const log = logger24 ?? defaultLogger6;
10289
10225
  const path6 = projectPath || process.cwd();
10290
10226
  if (path6 === "/" || path6 === "") {
10291
10227
  const homePath = homedir();
10292
- logger19.info("Invalid project path detected, using home directory", {
10228
+ log.info("Invalid project path detected, using home directory", {
10293
10229
  originalPath: path6,
10294
10230
  normalizedPath: homePath
10295
10231
  });
@@ -10312,14 +10248,18 @@ function createErrorResult(error, metadata) {
10312
10248
  metadata
10313
10249
  };
10314
10250
  }
10315
- async function safeExecute(operation, errorContext) {
10251
+ async function safeExecute(operation, errorContext, logger24) {
10252
+ const log = logger24 ?? defaultLogger6;
10316
10253
  try {
10317
10254
  const result = await operation();
10318
10255
  return createSuccessResult(result);
10319
10256
  } catch (error) {
10320
10257
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
10321
10258
  const contextualError = errorContext ? `${errorContext}: ${errorMessage}` : errorMessage;
10322
- logger19.error("Operation failed", error, { errorContext });
10259
+ const isExpectedError = errorMessage.includes("CONVERSATION_NOT_FOUND") || errorMessage.includes("Invalid workflow:");
10260
+ if (!isExpectedError) {
10261
+ log.error("Operation failed", error, { errorContext });
10262
+ }
10323
10263
  return createErrorResult(contextualError);
10324
10264
  }
10325
10265
  }
@@ -10383,14 +10323,16 @@ function generateWorkflowDescription(workflows) {
10383
10323
  description += "\u2022 **custom**: Use custom workflow from .vibe/workflows in your project\n\n";
10384
10324
  return description;
10385
10325
  }
10386
- function logHandlerExecution(handlerName, args) {
10387
- logger19.debug(`Executing ${handlerName} handler`, {
10326
+ function logHandlerExecution(handlerName, args, logger24) {
10327
+ const log = logger24 ?? defaultLogger6;
10328
+ log.debug(`Executing ${handlerName} handler`, {
10388
10329
  handlerName,
10389
10330
  argsKeys: Object.keys(args || {})
10390
10331
  });
10391
10332
  }
10392
- function logHandlerCompletion(handlerName, result) {
10393
- logger19.debug(`Completed ${handlerName} handler`, {
10333
+ function logHandlerCompletion(handlerName, result, logger24) {
10334
+ const log = logger24 ?? defaultLogger6;
10335
+ log.debug(`Completed ${handlerName} handler`, {
10394
10336
  handlerName,
10395
10337
  success: result.success,
10396
10338
  hasData: !!result.data,
@@ -10418,12 +10360,14 @@ var notificationService = new NotificationService();
10418
10360
  var PluginRegistry = class {
10419
10361
  plugins = /* @__PURE__ */ new Map();
10420
10362
  /**
10421
- * Register a plugin if it's enabled
10363
+ * Register a plugin.
10364
+ *
10365
+ * Note: Plugins are always registered regardless of isEnabled() state.
10366
+ * The isEnabled() check happens at hook execution time in getEnabledPlugins().
10367
+ * This allows plugins to activate/deactivate dynamically based on conditions
10368
+ * that may change after registration (e.g., backend availability).
10422
10369
  */
10423
10370
  registerPlugin(plugin) {
10424
- if (!plugin.isEnabled()) {
10425
- return;
10426
- }
10427
10371
  const name = plugin.getName();
10428
10372
  if (this.plugins.has(name)) {
10429
10373
  throw new Error(`Plugin with name '${name}' is already registered`);
@@ -10535,11 +10479,13 @@ var PluginRegistry = class {
10535
10479
  this.plugins.clear();
10536
10480
  }
10537
10481
  };
10538
- var logger20 = createLogger("BeadsTaskBackendClient");
10482
+ var defaultLogger7 = createLogger("BeadsTaskBackendClient");
10539
10483
  var BeadsTaskBackendClient = class {
10540
10484
  projectPath;
10541
- constructor(projectPath) {
10485
+ logger;
10486
+ constructor(projectPath, logger24) {
10542
10487
  this.projectPath = projectPath;
10488
+ this.logger = logger24 ?? defaultLogger7;
10543
10489
  }
10544
10490
  /**
10545
10491
  * Execute a beads command safely
@@ -10547,7 +10493,7 @@ var BeadsTaskBackendClient = class {
10547
10493
  async executeBeadsCommand(args) {
10548
10494
  try {
10549
10495
  const command = `bd ${args.join(" ")}`;
10550
- logger20.debug("Executing beads command", {
10496
+ this.logger.debug("Executing beads command", {
10551
10497
  command,
10552
10498
  projectPath: this.projectPath
10553
10499
  });
@@ -10559,7 +10505,7 @@ var BeadsTaskBackendClient = class {
10559
10505
  return { success: true, stdout };
10560
10506
  } catch (error) {
10561
10507
  const execError = error;
10562
- logger20.warn("Beads command failed", {
10508
+ this.logger.warn("Beads command failed", {
10563
10509
  args,
10564
10510
  error: error instanceof Error ? error.message : String(error),
10565
10511
  stderr: execError.stderr,
@@ -10690,18 +10636,29 @@ var BeadsTaskBackendClient = class {
10690
10636
  }
10691
10637
  }
10692
10638
  };
10693
- var logger21 = createLogger("BeadsPlugin");
10694
10639
  var BeadsPlugin = class {
10695
10640
  projectPath;
10696
10641
  beadsStateManager;
10697
10642
  beadsTaskBackendClient;
10698
10643
  planManager;
10644
+ logger;
10645
+ loggerFactory;
10699
10646
  constructor(options) {
10700
10647
  this.projectPath = options.projectPath;
10701
- this.beadsStateManager = new BeadsStateManager(this.projectPath);
10702
- this.beadsTaskBackendClient = new BeadsTaskBackendClient(this.projectPath);
10648
+ this.loggerFactory = options.loggerFactory;
10649
+ this.logger = options.loggerFactory ? options.loggerFactory("BeadsPlugin") : createLogger("BeadsPlugin");
10650
+ this.beadsStateManager = new BeadsStateManager(
10651
+ this.projectPath,
10652
+ options.loggerFactory ? options.loggerFactory("BeadsStateManager") : void 0
10653
+ );
10654
+ this.beadsTaskBackendClient = new BeadsTaskBackendClient(
10655
+ this.projectPath,
10656
+ options.loggerFactory ? options.loggerFactory("BeadsTaskBackendClient") : void 0
10657
+ );
10703
10658
  this.planManager = new PlanManager();
10704
- logger21.debug("BeadsPlugin initialized", { projectPath: this.projectPath });
10659
+ this.logger.debug("BeadsPlugin initialized", {
10660
+ projectPath: this.projectPath
10661
+ });
10705
10662
  }
10706
10663
  getName() {
10707
10664
  return "BeadsPlugin";
@@ -10710,9 +10667,9 @@ var BeadsPlugin = class {
10710
10667
  return 100;
10711
10668
  }
10712
10669
  isEnabled() {
10713
- const taskBackendConfig = TaskBackendManager.detectTaskBackend();
10670
+ const taskBackendConfig = TaskBackendManager.detectTaskBackend(this.logger);
10714
10671
  const enabled = taskBackendConfig.backend === "beads" && taskBackendConfig.isAvailable;
10715
- logger21.debug("BeadsPlugin enablement check", {
10672
+ this.logger.debug("BeadsPlugin enablement check", {
10716
10673
  backend: taskBackendConfig.backend,
10717
10674
  isAvailable: taskBackendConfig.isAvailable,
10718
10675
  autoDetected: !process.env["TASK_BACKEND"],
@@ -10724,7 +10681,8 @@ var BeadsPlugin = class {
10724
10681
  return {
10725
10682
  afterStartDevelopment: this.handleAfterStartDevelopment.bind(this),
10726
10683
  beforePhaseTransition: this.handleBeforePhaseTransition.bind(this),
10727
- afterPlanFileCreated: this.handleAfterPlanFileCreated.bind(this)
10684
+ afterPlanFileCreated: this.handleAfterPlanFileCreated.bind(this),
10685
+ afterInstructionsGenerated: this.handleAfterInstructionsGenerated.bind(this)
10728
10686
  };
10729
10687
  }
10730
10688
  /**
@@ -10732,7 +10690,7 @@ var BeadsPlugin = class {
10732
10690
  * Replaces validateBeadsTaskCompletion() method from proceed-to-phase.ts
10733
10691
  */
10734
10692
  async handleBeforePhaseTransition(context, currentPhase, targetPhase) {
10735
- logger21.info(
10693
+ this.logger.info(
10736
10694
  "BeadsPlugin: Validating task completion before phase transition",
10737
10695
  {
10738
10696
  conversationId: context.conversationId,
@@ -10747,7 +10705,7 @@ var BeadsPlugin = class {
10747
10705
  targetPhase,
10748
10706
  context.projectPath
10749
10707
  );
10750
- logger21.info(
10708
+ this.logger.info(
10751
10709
  "BeadsPlugin: Task validation passed, allowing phase transition",
10752
10710
  {
10753
10711
  conversationId: context.conversationId,
@@ -10756,7 +10714,7 @@ var BeadsPlugin = class {
10756
10714
  }
10757
10715
  );
10758
10716
  } catch (error) {
10759
- logger21.info(
10717
+ this.logger.info(
10760
10718
  "BeadsPlugin: Task validation failed, blocking phase transition",
10761
10719
  {
10762
10720
  conversationId: context.conversationId,
@@ -10774,20 +10732,25 @@ var BeadsPlugin = class {
10774
10732
  * Implements graceful degradation: continues app operation even if beads operations fail
10775
10733
  */
10776
10734
  async handleAfterStartDevelopment(context, args, _result) {
10777
- logger21.info("BeadsPlugin: Setting up beads integration", {
10735
+ this.logger.info("BeadsPlugin: Setting up beads integration", {
10778
10736
  conversationId: context.conversationId,
10779
10737
  workflow: args.workflow,
10780
10738
  projectPath: context.projectPath
10781
10739
  });
10782
10740
  if (!context.stateMachine) {
10783
- logger21.error("BeadsPlugin: State machine not provided in plugin context");
10784
- logger21.warn(
10741
+ this.logger.error(
10742
+ "BeadsPlugin: State machine not provided in plugin context"
10743
+ );
10744
+ this.logger.warn(
10785
10745
  "BeadsPlugin: Beads integration disabled - continuing without beads"
10786
10746
  );
10787
10747
  return;
10788
10748
  }
10789
10749
  try {
10790
- const beadsIntegration = new BeadsIntegration(context.projectPath);
10750
+ const beadsIntegration = new BeadsIntegration(
10751
+ context.projectPath,
10752
+ this.loggerFactory ? this.loggerFactory("BeadsIntegration") : void 0
10753
+ );
10791
10754
  const projectName = getPathBasename(
10792
10755
  context.projectPath,
10793
10756
  "Unknown Project"
@@ -10799,7 +10762,7 @@ var BeadsPlugin = class {
10799
10762
  );
10800
10763
  goalDescription = this.extractGoalFromPlan(planFileContent);
10801
10764
  } catch (error) {
10802
- logger21.warn("BeadsPlugin: Could not extract goal from plan file", {
10765
+ this.logger.warn("BeadsPlugin: Could not extract goal from plan file", {
10803
10766
  error: error instanceof Error ? error.message : String(error),
10804
10767
  planFilePath: context.planFilePath
10805
10768
  });
@@ -10815,7 +10778,7 @@ var BeadsPlugin = class {
10815
10778
  );
10816
10779
  } catch (error) {
10817
10780
  const errorMsg = error instanceof Error ? error.message : String(error);
10818
- logger21.warn(
10781
+ this.logger.warn(
10819
10782
  "BeadsPlugin: Failed to create beads project epic - continuing without beads integration",
10820
10783
  {
10821
10784
  error: errorMsg,
@@ -10833,7 +10796,7 @@ var BeadsPlugin = class {
10833
10796
  );
10834
10797
  } catch (error) {
10835
10798
  const errorMsg = error instanceof Error ? error.message : String(error);
10836
- logger21.warn(
10799
+ this.logger.warn(
10837
10800
  "BeadsPlugin: Failed to create beads phase tasks - continuing without phase tracking",
10838
10801
  {
10839
10802
  error: errorMsg,
@@ -10846,7 +10809,7 @@ var BeadsPlugin = class {
10846
10809
  await beadsIntegration.createPhaseDependencies(phaseTasks);
10847
10810
  } catch (error) {
10848
10811
  const errorMsg = error instanceof Error ? error.message : String(error);
10849
- logger21.warn(
10812
+ this.logger.warn(
10850
10813
  "BeadsPlugin: Failed to create phase dependencies - continuing without dependencies",
10851
10814
  {
10852
10815
  error: errorMsg,
@@ -10861,7 +10824,7 @@ var BeadsPlugin = class {
10861
10824
  );
10862
10825
  } catch (error) {
10863
10826
  const errorMsg = error instanceof Error ? error.message : String(error);
10864
- logger21.warn(
10827
+ this.logger.warn(
10865
10828
  "BeadsPlugin: Failed to update plan file with beads task IDs - continuing without plan file updates",
10866
10829
  {
10867
10830
  error: errorMsg,
@@ -10877,7 +10840,7 @@ var BeadsPlugin = class {
10877
10840
  );
10878
10841
  } catch (error) {
10879
10842
  const errorMsg = error instanceof Error ? error.message : String(error);
10880
- logger21.warn(
10843
+ this.logger.warn(
10881
10844
  "BeadsPlugin: Failed to create beads state - continuing without state persistence",
10882
10845
  {
10883
10846
  error: errorMsg,
@@ -10885,7 +10848,7 @@ var BeadsPlugin = class {
10885
10848
  }
10886
10849
  );
10887
10850
  }
10888
- logger21.info("BeadsPlugin: Beads integration setup complete", {
10851
+ this.logger.info("BeadsPlugin: Beads integration setup complete", {
10889
10852
  conversationId: context.conversationId,
10890
10853
  epicId,
10891
10854
  phaseCount: phaseTasks?.length || 0,
@@ -10893,7 +10856,7 @@ var BeadsPlugin = class {
10893
10856
  });
10894
10857
  } catch (error) {
10895
10858
  const errorMsg = error instanceof Error ? error.message : String(error);
10896
- logger21.warn(
10859
+ this.logger.warn(
10897
10860
  "BeadsPlugin: Unexpected error during beads integration setup - continuing application without beads",
10898
10861
  {
10899
10862
  error: errorMsg,
@@ -10914,11 +10877,127 @@ var BeadsPlugin = class {
10914
10877
  * This hook ensures the plan has the proper structure to receive them.
10915
10878
  */
10916
10879
  async handleAfterPlanFileCreated(_context, planFilePath, content) {
10917
- logger21.debug("BeadsPlugin: afterPlanFileCreated hook invoked", {
10880
+ this.logger.debug("BeadsPlugin: afterPlanFileCreated hook invoked", {
10918
10881
  planFilePath,
10919
10882
  contentLength: content.length
10920
10883
  });
10921
- return content;
10884
+ let transformed = content;
10885
+ transformed = transformed.replace(
10886
+ /### Tasks\n- \[ \] \*Tasks will be added as they are identified\*\n\n### Completed\n- \[x\] Created development plan file/g,
10887
+ "<!-- beads-phase-id: TBD -->\n### Tasks\n\n*Tasks managed via `bd` CLI*"
10888
+ );
10889
+ transformed = transformed.replace(
10890
+ /### Tasks\n- \[ \] \*To be added when this phase becomes active\*\n\n### Completed\n\*None yet\*/g,
10891
+ "<!-- beads-phase-id: TBD -->\n### Tasks\n\n*Tasks managed via `bd` CLI*"
10892
+ );
10893
+ transformed = transformed.replace(
10894
+ /\*This plan is maintained by the LLM\. Tool responses provide guidance on which section to focus on and what tasks to work on\.\*/,
10895
+ "*This plan is maintained by the LLM and uses beads CLI for task management. Tool responses provide guidance on which bd commands to use for task management.*"
10896
+ );
10897
+ this.logger.debug("BeadsPlugin: Plan file transformed for beads", {
10898
+ planFilePath,
10899
+ originalLength: content.length,
10900
+ transformedLength: transformed.length,
10901
+ wasModified: content !== transformed
10902
+ });
10903
+ return transformed;
10904
+ }
10905
+ /**
10906
+ * Handle afterInstructionsGenerated hook
10907
+ * Enriches instructions with beads-specific task management guidance
10908
+ */
10909
+ async handleAfterInstructionsGenerated(context, instructions) {
10910
+ this.logger.debug("BeadsPlugin: afterInstructionsGenerated hook invoked", {
10911
+ phase: instructions.phase,
10912
+ instructionSource: instructions.instructionSource,
10913
+ planFilePath: instructions.planFilePath
10914
+ });
10915
+ const beadsGuidance = await this.generateBeadsGuidance(
10916
+ context,
10917
+ instructions
10918
+ );
10919
+ let enhanced = instructions.instructions;
10920
+ enhanced += `
10921
+
10922
+ Log decisions in plan file. Use ONLY \`bd\` CLI for tasks (not your own todo tools).${beadsGuidance}`;
10923
+ if (context.planFileExists === false) {
10924
+ enhanced += "\n\n**Note**: Plan file will be created when you first update it.";
10925
+ }
10926
+ enhanced += "\n\nCall `whats_next()` after user messages.";
10927
+ this.logger.debug(
10928
+ "BeadsPlugin: Instructions enriched with beads guidance",
10929
+ {
10930
+ originalLength: instructions.instructions.length,
10931
+ enrichedLength: enhanced.length
10932
+ }
10933
+ );
10934
+ return {
10935
+ ...instructions,
10936
+ instructions: enhanced
10937
+ };
10938
+ }
10939
+ /**
10940
+ * Generate beads-specific task management guidance
10941
+ */
10942
+ async generateBeadsGuidance(_context, instructions) {
10943
+ if (instructions.instructionSource === "whats_next" || instructions.instructionSource === "start_development") {
10944
+ const phaseTaskId = await this.extractPhaseTaskIdFromPlanFile(
10945
+ instructions.planFilePath,
10946
+ instructions.phase
10947
+ );
10948
+ if (!phaseTaskId) {
10949
+ return `
10950
+
10951
+ **Task Management (bd CLI):**
10952
+ Create tasks as sub-tasks of phase task: \`bd create 'title' --parent <phase-task-id>\`
10953
+ List open tasks: \`bd list --parent <phase-task-id> --status open\`
10954
+ Complete tasks: \`bd close <id>\``;
10955
+ }
10956
+ return `
10957
+
10958
+ **Task Management (bd CLI) - Phase: ${phaseTaskId}**
10959
+ Create tasks as sub-tasks: \`bd create 'title' --parent ${phaseTaskId}\`
10960
+ List open tasks: \`bd list --parent ${phaseTaskId} --status open\`
10961
+ Complete tasks: \`bd close <id>\``;
10962
+ }
10963
+ return "";
10964
+ }
10965
+ /**
10966
+ * Extract phase task ID from plan file
10967
+ */
10968
+ async extractPhaseTaskIdFromPlanFile(planFilePath, phase) {
10969
+ try {
10970
+ const { readFile: readFile5 } = await import("fs/promises");
10971
+ const content = await readFile5(planFilePath, "utf-8");
10972
+ const phaseName = this.capitalizePhase(phase);
10973
+ const phaseHeader = `## ${phaseName}`;
10974
+ const lines = content.split("\n");
10975
+ let foundPhaseHeader = false;
10976
+ for (const line of lines) {
10977
+ if (line.trim() === phaseHeader) {
10978
+ foundPhaseHeader = true;
10979
+ continue;
10980
+ }
10981
+ if (foundPhaseHeader && line.includes("beads-phase-id:")) {
10982
+ const match = line.match(/beads-phase-id:\s*([\w\d.-]+)/);
10983
+ if (match && match[1] && match[1] !== "TBD") {
10984
+ return match[1];
10985
+ }
10986
+ }
10987
+ if (foundPhaseHeader && line.startsWith("##") && line !== phaseHeader) {
10988
+ break;
10989
+ }
10990
+ }
10991
+ return null;
10992
+ } catch (_error) {
10993
+ return null;
10994
+ }
10995
+ }
10996
+ /**
10997
+ * Capitalize phase name for display
10998
+ */
10999
+ capitalizePhase(phase) {
11000
+ return phase.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
10922
11001
  }
10923
11002
  /**
10924
11003
  * Validate beads task completion before phase transition
@@ -10931,14 +11010,14 @@ var BeadsPlugin = class {
10931
11010
  isAvailable = await this.beadsTaskBackendClient.isAvailable();
10932
11011
  } catch (error) {
10933
11012
  const errorMsg = error instanceof Error ? error.message : String(error);
10934
- logger21.warn("BeadsPlugin: Failed to check beads availability", {
11013
+ this.logger.warn("BeadsPlugin: Failed to check beads availability", {
10935
11014
  error: errorMsg,
10936
11015
  conversationId
10937
11016
  });
10938
11017
  return;
10939
11018
  }
10940
11019
  if (!isAvailable) {
10941
- logger21.debug(
11020
+ this.logger.debug(
10942
11021
  "BeadsPlugin: Skipping beads task validation - beads CLI not available",
10943
11022
  {
10944
11023
  conversationId,
@@ -10956,7 +11035,7 @@ var BeadsPlugin = class {
10956
11035
  );
10957
11036
  } catch (error) {
10958
11037
  const errorMsg = error instanceof Error ? error.message : String(error);
10959
- logger21.warn("BeadsPlugin: Failed to get beads phase task ID", {
11038
+ this.logger.warn("BeadsPlugin: Failed to get beads phase task ID", {
10960
11039
  error: errorMsg,
10961
11040
  conversationId,
10962
11041
  currentPhase
@@ -10964,7 +11043,7 @@ var BeadsPlugin = class {
10964
11043
  return;
10965
11044
  }
10966
11045
  if (!currentPhaseTaskId) {
10967
- logger21.debug(
11046
+ this.logger.debug(
10968
11047
  "BeadsPlugin: No beads phase task ID found for current phase",
10969
11048
  {
10970
11049
  conversationId,
@@ -10975,7 +11054,7 @@ var BeadsPlugin = class {
10975
11054
  );
10976
11055
  return;
10977
11056
  }
10978
- logger21.debug(
11057
+ this.logger.debug(
10979
11058
  "BeadsPlugin: Checking for incomplete beads tasks using task backend client",
10980
11059
  {
10981
11060
  conversationId,
@@ -10990,7 +11069,7 @@ var BeadsPlugin = class {
10990
11069
  );
10991
11070
  } catch (error) {
10992
11071
  const errorMsg = error instanceof Error ? error.message : String(error);
10993
- logger21.warn(
11072
+ this.logger.warn(
10994
11073
  "BeadsPlugin: Failed to validate tasks with beads backend",
10995
11074
  {
10996
11075
  error: errorMsg,
@@ -11002,18 +11081,9 @@ var BeadsPlugin = class {
11002
11081
  }
11003
11082
  if (!validationResult.valid) {
11004
11083
  const incompleteTasks = validationResult.openTasks || [];
11005
- const taskDetails = incompleteTasks.map((task) => ` \u2022 ${task.id} - ${task.title || "Untitled task"}`).join("\n");
11006
- const errorMessage = `Cannot proceed to ${targetPhase} - ${incompleteTasks.length} incomplete task(s) in current phase "${currentPhase}":
11007
-
11008
- ${taskDetails}
11009
-
11010
- To proceed, check the in-progress-tasks using:
11011
-
11012
- bd list --parent ${currentPhaseTaskId} --status open
11013
-
11014
- You can also defer tasks if they're no longer needed:
11015
- bd defer <task-id> --until tomorrow`;
11016
- logger21.info(
11084
+ const taskIds = incompleteTasks.map((t) => t.id).join(", ");
11085
+ const errorMessage = `${incompleteTasks.length} incomplete task(s) in ${currentPhase}: ${taskIds}. Complete or defer (\`bd defer <id>\`) before proceeding.`;
11086
+ this.logger.info(
11017
11087
  "BeadsPlugin: Blocking phase transition due to incomplete beads tasks",
11018
11088
  {
11019
11089
  conversationId,
@@ -11026,7 +11096,7 @@ You can also defer tasks if they're no longer needed:
11026
11096
  );
11027
11097
  throw new Error(errorMessage);
11028
11098
  }
11029
- logger21.info(
11099
+ this.logger.info(
11030
11100
  "BeadsPlugin: All beads tasks completed in current phase, allowing transition",
11031
11101
  {
11032
11102
  conversationId,
@@ -11040,7 +11110,7 @@ You can also defer tasks if they're no longer needed:
11040
11110
  throw error;
11041
11111
  }
11042
11112
  const errorMessage = error instanceof Error ? error.message : String(error);
11043
- logger21.warn(
11113
+ this.logger.warn(
11044
11114
  "BeadsPlugin: Beads task validation failed, allowing transition to proceed",
11045
11115
  {
11046
11116
  error: errorMessage,
@@ -11093,13 +11163,13 @@ You can also defer tasks if they're no longer needed:
11093
11163
  */
11094
11164
  async updatePlanFileWithPhaseTaskIds(planFilePath, phaseTasks) {
11095
11165
  try {
11096
- const { readFile: readFile6, writeFile: writeFile6 } = await import("fs/promises");
11166
+ const { readFile: readFile5, writeFile: writeFile5 } = await import("fs/promises");
11097
11167
  let content;
11098
11168
  try {
11099
- content = await readFile6(planFilePath, "utf-8");
11169
+ content = await readFile5(planFilePath, "utf-8");
11100
11170
  } catch (error) {
11101
11171
  const errorMsg = error instanceof Error ? error.message : String(error);
11102
- logger21.warn("BeadsPlugin: Failed to read plan file for update", {
11172
+ this.logger.warn("BeadsPlugin: Failed to read plan file for update", {
11103
11173
  error: errorMsg,
11104
11174
  planFilePath
11105
11175
  });
@@ -11119,7 +11189,7 @@ You can also defer tasks if they're no longer needed:
11119
11189
  }
11120
11190
  const remainingTBDs = content.match(/<!-- beads-phase-id: TBD -->/g);
11121
11191
  if (remainingTBDs && remainingTBDs.length > 0) {
11122
- logger21.warn(
11192
+ this.logger.warn(
11123
11193
  "BeadsPlugin: Failed to replace all TBD placeholders in plan file",
11124
11194
  {
11125
11195
  planFilePath,
@@ -11129,16 +11199,16 @@ You can also defer tasks if they're no longer needed:
11129
11199
  );
11130
11200
  }
11131
11201
  try {
11132
- await writeFile6(planFilePath, content, "utf-8");
11202
+ await writeFile5(planFilePath, content, "utf-8");
11133
11203
  } catch (error) {
11134
11204
  const errorMsg = error instanceof Error ? error.message : String(error);
11135
- logger21.warn("BeadsPlugin: Failed to write updated plan file", {
11205
+ this.logger.warn("BeadsPlugin: Failed to write updated plan file", {
11136
11206
  error: errorMsg,
11137
11207
  planFilePath
11138
11208
  });
11139
11209
  return;
11140
11210
  }
11141
- logger21.info(
11211
+ this.logger.info(
11142
11212
  "BeadsPlugin: Successfully updated plan file with beads phase task IDs",
11143
11213
  {
11144
11214
  planFilePath,
@@ -11150,7 +11220,7 @@ You can also defer tasks if they're no longer needed:
11150
11220
  );
11151
11221
  } catch (error) {
11152
11222
  const errorMsg = error instanceof Error ? error.message : String(error);
11153
- logger21.warn(
11223
+ this.logger.warn(
11154
11224
  "BeadsPlugin: Unexpected error while updating plan file with phase task IDs",
11155
11225
  {
11156
11226
  error: errorMsg,
@@ -11160,13 +11230,13 @@ You can also defer tasks if they're no longer needed:
11160
11230
  }
11161
11231
  }
11162
11232
  };
11163
- var logger22 = createLogger("CommitPlugin");
11233
+ var logger14 = createLogger("CommitPlugin");
11164
11234
  var CommitPlugin = class {
11165
11235
  projectPath;
11166
11236
  initialCommitHash;
11167
11237
  constructor(options) {
11168
11238
  this.projectPath = options.projectPath;
11169
- logger22.debug("CommitPlugin initialized", { projectPath: this.projectPath });
11239
+ logger14.debug("CommitPlugin initialized", { projectPath: this.projectPath });
11170
11240
  }
11171
11241
  getName() {
11172
11242
  return "CommitPlugin";
@@ -11177,7 +11247,7 @@ var CommitPlugin = class {
11177
11247
  isEnabled() {
11178
11248
  const behavior = process.env.COMMIT_BEHAVIOR;
11179
11249
  const enabled = behavior && ["step", "phase", "end", "none"].includes(behavior);
11180
- logger22.debug("CommitPlugin enablement check", {
11250
+ logger14.debug("CommitPlugin enablement check", {
11181
11251
  COMMIT_BEHAVIOR: behavior,
11182
11252
  enabled: !!enabled
11183
11253
  });
@@ -11195,7 +11265,7 @@ var CommitPlugin = class {
11195
11265
  * Store initial commit hash for potential squashing later
11196
11266
  */
11197
11267
  async handleAfterStartDevelopment(context, _args, _result) {
11198
- logger22.info("CommitPlugin: Setting up commit behavior", {
11268
+ logger14.info("CommitPlugin: Setting up commit behavior", {
11199
11269
  conversationId: context.conversationId,
11200
11270
  behavior: process.env.COMMIT_BEHAVIOR,
11201
11271
  projectPath: context.projectPath
@@ -11203,13 +11273,13 @@ var CommitPlugin = class {
11203
11273
  try {
11204
11274
  if (GitManager.isGitRepository(context.projectPath)) {
11205
11275
  this.initialCommitHash = GitManager.getCurrentCommitHash(context.projectPath) || void 0;
11206
- logger22.debug("CommitPlugin: Stored initial commit hash", {
11276
+ logger14.debug("CommitPlugin: Stored initial commit hash", {
11207
11277
  conversationId: context.conversationId,
11208
11278
  initialCommitHash: this.initialCommitHash
11209
11279
  });
11210
11280
  }
11211
11281
  } catch (error) {
11212
- logger22.warn("CommitPlugin: Failed to get initial commit hash", {
11282
+ logger14.warn("CommitPlugin: Failed to get initial commit hash", {
11213
11283
  error: error instanceof Error ? error.message : String(error),
11214
11284
  conversationId: context.conversationId
11215
11285
  });
@@ -11224,7 +11294,7 @@ var CommitPlugin = class {
11224
11294
  if (behavior !== "phase" && behavior !== "step") {
11225
11295
  return;
11226
11296
  }
11227
- logger22.info("CommitPlugin: Creating WIP commit before phase transition", {
11297
+ logger14.info("CommitPlugin: Creating WIP commit before phase transition", {
11228
11298
  conversationId: context.conversationId,
11229
11299
  currentPhase,
11230
11300
  targetPhase,
@@ -11232,28 +11302,28 @@ var CommitPlugin = class {
11232
11302
  });
11233
11303
  try {
11234
11304
  if (!GitManager.isGitRepository(context.projectPath)) {
11235
- logger22.debug("CommitPlugin: Not a git repository, skipping commit");
11305
+ logger14.debug("CommitPlugin: Not a git repository, skipping commit");
11236
11306
  return;
11237
11307
  }
11238
11308
  if (!GitManager.hasUncommittedChanges(context.projectPath)) {
11239
- logger22.debug("CommitPlugin: No uncommitted changes, skipping commit");
11309
+ logger14.debug("CommitPlugin: No uncommitted changes, skipping commit");
11240
11310
  return;
11241
11311
  }
11242
11312
  const message = `WIP: transition to ${targetPhase}`;
11243
11313
  const success = GitManager.createCommit(message, context.projectPath);
11244
11314
  if (success) {
11245
- logger22.info("CommitPlugin: Created WIP commit successfully", {
11315
+ logger14.info("CommitPlugin: Created WIP commit successfully", {
11246
11316
  conversationId: context.conversationId,
11247
11317
  message
11248
11318
  });
11249
11319
  } else {
11250
- logger22.warn("CommitPlugin: Failed to create WIP commit", {
11320
+ logger14.warn("CommitPlugin: Failed to create WIP commit", {
11251
11321
  conversationId: context.conversationId,
11252
11322
  message
11253
11323
  });
11254
11324
  }
11255
11325
  } catch (error) {
11256
- logger22.warn("CommitPlugin: Error during phase transition commit", {
11326
+ logger14.warn("CommitPlugin: Error during phase transition commit", {
11257
11327
  error: error instanceof Error ? error.message : String(error),
11258
11328
  conversationId: context.conversationId
11259
11329
  });
@@ -11268,7 +11338,7 @@ var CommitPlugin = class {
11268
11338
  if (!behavior || behavior === "none") {
11269
11339
  return content;
11270
11340
  }
11271
- logger22.debug("CommitPlugin: Adding final commit task to plan file", {
11341
+ logger14.debug("CommitPlugin: Adding final commit task to plan file", {
11272
11342
  conversationId: context.conversationId,
11273
11343
  behavior,
11274
11344
  planFilePath
@@ -11292,7 +11362,7 @@ var CommitPlugin = class {
11292
11362
  }
11293
11363
  }
11294
11364
  if (finalPhaseIndex === -1) {
11295
- logger22.warn(
11365
+ logger14.warn(
11296
11366
  "CommitPlugin: Could not find final phase to add commit task"
11297
11367
  );
11298
11368
  return content;
@@ -11318,14 +11388,14 @@ var CommitPlugin = class {
11318
11388
  lines.splice(finalPhaseIndex + 1, 0, "", "### Tasks", commitTask);
11319
11389
  }
11320
11390
  const updatedContent = lines.join("\n");
11321
- logger22.info("CommitPlugin: Added final commit task to plan file", {
11391
+ logger14.info("CommitPlugin: Added final commit task to plan file", {
11322
11392
  conversationId: context.conversationId,
11323
11393
  behavior,
11324
11394
  commitTask
11325
11395
  });
11326
11396
  return updatedContent;
11327
11397
  } catch (error) {
11328
- logger22.warn("CommitPlugin: Failed to add commit task to plan file", {
11398
+ logger14.warn("CommitPlugin: Failed to add commit task to plan file", {
11329
11399
  error: error instanceof Error ? error.message : String(error),
11330
11400
  conversationId: context.conversationId
11331
11401
  });
@@ -11333,408 +11403,15 @@ var CommitPlugin = class {
11333
11403
  }
11334
11404
  }
11335
11405
  };
11336
- var logger23 = createLogger("BeadsPlanManager");
11337
- var BeadsPlanManager = class {
11338
- stateMachine = null;
11339
- /**
11340
- * Set the state machine definition for dynamic plan generation
11341
- */
11342
- setStateMachine(stateMachine) {
11343
- this.stateMachine = stateMachine;
11344
- logger23.debug("State machine set for beads plan manager", {
11345
- name: stateMachine.name,
11346
- phases: Object.keys(stateMachine.states)
11347
- });
11348
- }
11349
- /**
11350
- * Set the task backend configuration
11351
- */
11352
- setTaskBackend(taskBackend) {
11353
- logger23.debug("Task backend set for beads plan manager", {
11354
- backend: taskBackend.backend,
11355
- available: taskBackend.isAvailable
11356
- });
11357
- }
11358
- /**
11359
- * Get plan file information
11360
- */
11361
- async getPlanFileInfo(planFilePath) {
11362
- try {
11363
- await access6(planFilePath);
11364
- const content = await readFile4(planFilePath, "utf-8");
11365
- return {
11366
- path: planFilePath,
11367
- exists: true,
11368
- content
11369
- };
11370
- } catch (_error) {
11371
- return {
11372
- path: planFilePath,
11373
- exists: false
11374
- };
11375
- }
11376
- }
11377
- /**
11378
- * Create initial plan file if it doesn't exist
11379
- */
11380
- async ensurePlanFile(planFilePath, projectPath, gitBranch) {
11381
- logger23.debug("Ensuring beads plan file exists", {
11382
- planFilePath,
11383
- projectPath,
11384
- gitBranch
11385
- });
11386
- const planInfo = await this.getPlanFileInfo(planFilePath);
11387
- if (!planInfo.exists) {
11388
- logger23.info("Plan file not found, creating beads-optimized plan", {
11389
- planFilePath
11390
- });
11391
- await this.createInitialBeadsPlanFile(
11392
- planFilePath,
11393
- projectPath,
11394
- gitBranch
11395
- );
11396
- logger23.info("Beads plan file created successfully", { planFilePath });
11397
- } else {
11398
- logger23.debug("Plan file already exists", { planFilePath });
11399
- }
11400
- }
11401
- /**
11402
- * Create initial plan file optimized for beads workflow
11403
- */
11404
- async createInitialBeadsPlanFile(planFilePath, projectPath, gitBranch) {
11405
- logger23.debug("Creating beads-optimized plan file", { planFilePath });
11406
- try {
11407
- await mkdir4(dirname6(planFilePath), { recursive: true });
11408
- logger23.debug("Plan file directory ensured", {
11409
- directory: dirname6(planFilePath)
11410
- });
11411
- const projectName = getPathBasename(projectPath, "Unknown Project");
11412
- const branchInfo = gitBranch !== "no-git" ? ` (${gitBranch} branch)` : "";
11413
- const initialContent = this.generateBeadsInitialPlanContent(
11414
- projectName,
11415
- branchInfo
11416
- );
11417
- await writeFile4(planFilePath, initialContent, "utf-8");
11418
- logger23.info("Beads plan file written successfully", {
11419
- planFilePath,
11420
- contentLength: initialContent.length,
11421
- projectName
11422
- });
11423
- } catch (error) {
11424
- logger23.error("Failed to create beads plan file", error, {
11425
- planFilePath
11426
- });
11427
- throw error;
11428
- }
11429
- }
11430
- /**
11431
- * Generate initial plan file content optimized for beads workflow
11432
- */
11433
- generateBeadsInitialPlanContent(projectName, branchInfo) {
11434
- const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
11435
- if (!this.stateMachine) {
11436
- throw new Error(
11437
- "State machine not set. This should not happen as state machine is always loaded."
11438
- );
11439
- }
11440
- const phases = Object.keys(this.stateMachine.states);
11441
- const initialPhase = this.stateMachine.initial_state;
11442
- const documentationUrl = this.generateWorkflowDocumentationUrl(
11443
- this.stateMachine.name
11444
- );
11445
- let content = `# Development Plan: ${projectName}${branchInfo}
11446
-
11447
- *Generated on ${timestamp2} by Vibe Feature MCP*
11448
- *Workflow: ${documentationUrl ? "[" + this.stateMachine.name + "](" + documentationUrl + ")" : this.stateMachine.name}*
11449
-
11450
- ## Goal
11451
- *Define what you're building or fixing - this will be updated as requirements are gathered*
11452
-
11453
- ## ${this.capitalizePhase(initialPhase)}
11454
- <!-- beads-phase-id: TBD -->
11455
- ### Tasks
11456
-
11457
- *Tasks managed via \`bd\` CLI*
11458
-
11459
- `;
11460
- for (const phase of phases) {
11461
- if (phase !== initialPhase) {
11462
- content += `## ${this.capitalizePhase(phase)}
11463
- <!-- beads-phase-id: TBD -->
11464
- ### Tasks
11465
-
11466
- *Tasks managed via \`bd\` CLI*
11467
-
11468
- `;
11469
- }
11470
- }
11471
- content += `## Key Decisions
11472
- *Important decisions will be documented here as they are made*
11473
-
11474
- ## Notes
11475
- *Additional context and observations*
11476
-
11477
- ---
11478
- *This plan is maintained by the LLM and uses beads CLI for task management. Tool responses provide guidance on which bd commands to use for task management.*
11479
- `;
11480
- return content;
11481
- }
11482
- /**
11483
- * Update plan file with new content
11484
- */
11485
- async updatePlanFile(planFilePath, content) {
11486
- await mkdir4(dirname6(planFilePath), { recursive: true });
11487
- await writeFile4(planFilePath, content, "utf-8");
11488
- }
11489
- /**
11490
- * Get plan file content for LLM context
11491
- */
11492
- async getPlanFileContent(planFilePath) {
11493
- const planInfo = await this.getPlanFileInfo(planFilePath);
11494
- if (!planInfo.exists) {
11495
- return "Plan file does not exist yet. It will be created when the LLM updates it.";
11496
- }
11497
- return planInfo.content || "";
11498
- }
11499
- /**
11500
- * Generate phase-specific plan file guidance optimized for beads
11501
- */
11502
- generatePlanFileGuidance(phase) {
11503
- if (!this.stateMachine) {
11504
- throw new Error(
11505
- "State machine not set. This should not happen as state machine is always loaded."
11506
- );
11507
- }
11508
- const phaseDefinition = this.stateMachine.states[phase];
11509
- if (!phaseDefinition) {
11510
- logger23.warn("Unknown phase for beads plan file guidance", { phase });
11511
- return `Track key decisions and take notes in the plan file. Use bd CLI for all task management.`;
11512
- }
11513
- return `Track key decisions and take notes in the plan file. Use bd CLI exclusively for task management - never use checkboxes. Document important decisions in the Key Decisions section.`;
11514
- }
11515
- /**
11516
- * Delete plan file
11517
- */
11518
- async deletePlanFile(planFilePath) {
11519
- logger23.debug("Deleting beads plan file", { planFilePath });
11520
- try {
11521
- await access6(planFilePath);
11522
- const { unlink: unlink2 } = await import("fs/promises");
11523
- await unlink2(planFilePath);
11524
- logger23.info("Beads plan file deleted successfully", { planFilePath });
11525
- return true;
11526
- } catch (error) {
11527
- if (error.code === "ENOENT") {
11528
- logger23.debug("Beads plan file does not exist, nothing to delete", {
11529
- planFilePath
11530
- });
11531
- return true;
11532
- }
11533
- logger23.error("Failed to delete beads plan file", error, {
11534
- planFilePath
11535
- });
11536
- throw error;
11537
- }
11538
- }
11539
- /**
11540
- * Ensure plan file is deleted (verify deletion)
11541
- */
11542
- async ensurePlanFileDeleted(planFilePath) {
11543
- logger23.debug("Ensuring beads plan file is deleted", { planFilePath });
11544
- try {
11545
- await access6(planFilePath);
11546
- logger23.warn("Beads plan file still exists after deletion attempt", {
11547
- planFilePath
11548
- });
11549
- return false;
11550
- } catch (error) {
11551
- if (error.code === "ENOENT") {
11552
- logger23.debug("Beads plan file successfully deleted (does not exist)", {
11553
- planFilePath
11554
- });
11555
- return true;
11556
- }
11557
- logger23.error("Error checking beads plan file deletion", error, {
11558
- planFilePath
11559
- });
11560
- throw error;
11561
- }
11562
- }
11563
- /**
11564
- * Capitalize phase name for display
11565
- */
11566
- capitalizePhase(phase) {
11567
- return phase.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
11568
- }
11569
- /**
11570
- * Generate workflow documentation URL for predefined workflows
11571
- */
11572
- generateWorkflowDocumentationUrl(workflowName) {
11573
- if (workflowName === "custom") {
11574
- return void 0;
11575
- }
11576
- return `https://mrsimpson.github.io/responsible-vibe-mcp/workflows/${workflowName}`;
11577
- }
11578
- };
11579
- var BeadsInstructionGenerator = class {
11580
- projectDocsManager;
11581
- constructor() {
11582
- this.projectDocsManager = new ProjectDocsManager();
11583
- }
11584
- /**
11585
- * Set the state machine definition (interface requirement)
11586
- */
11587
- setStateMachine(_stateMachine) {
11588
- }
11589
- /**
11590
- * Generate comprehensive instructions optimized for beads workflow
11591
- */
11592
- async generateInstructions(baseInstructions, context) {
11593
- const substitutedInstructions = this.applyVariableSubstitution(
11594
- baseInstructions,
11595
- context.conversationContext.projectPath,
11596
- context.conversationContext.gitBranch
11597
- );
11598
- const enhancedInstructions = await this.enhanceBeadsInstructions(
11599
- substitutedInstructions,
11600
- context
11601
- );
11602
- return {
11603
- instructions: enhancedInstructions,
11604
- planFileGuidance: "Using beads CLI for task management - plan file serves as context only",
11605
- metadata: {
11606
- phase: context.phase,
11607
- planFilePath: context.conversationContext.planFilePath,
11608
- transitionReason: context.transitionReason,
11609
- isModeled: context.isModeled
11610
- }
11611
- };
11612
- }
11613
- /**
11614
- * Apply variable substitution to instructions
11615
- */
11616
- applyVariableSubstitution(instructions, projectPath, gitBranch) {
11617
- const substitutions = this.projectDocsManager.getVariableSubstitutions(
11618
- projectPath,
11619
- gitBranch
11620
- );
11621
- let result = instructions;
11622
- for (const [variable, value] of Object.entries(substitutions)) {
11623
- result = result.replace(
11624
- new RegExp(this.escapeRegExp(variable), "g"),
11625
- value
11626
- );
11627
- }
11628
- return result;
11629
- }
11630
- /**
11631
- * Escape special regex characters in variable names
11632
- */
11633
- escapeRegExp(string) {
11634
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11635
- }
11636
- /**
11637
- * Enhance instructions with beads-specific guidance
11638
- */
11639
- async enhanceBeadsInstructions(baseInstructions, context) {
11640
- const { planFileExists } = context;
11641
- const beadsTaskGuidance = await this.generateBeadsCLIGuidance(context);
11642
- let enhanced = `${baseInstructions}
11643
-
11644
- **Plan File Guidance:**
11645
- Use the plan file as memory for the current objective
11646
- - Update the "Key Decisions" section with important choices made
11647
- - Add relevant notes to help maintain context
11648
- - Do NOT enter tasks in the plan file, use beads CLI exclusively for task management
11649
-
11650
- ${beadsTaskGuidance}`;
11651
- if (!planFileExists) {
11652
- enhanced += "\n\n**Note**: Plan file will be created when you first update it.";
11653
- }
11654
- enhanced += `
11655
-
11656
- **Important Reminders:**
11657
- - Use ONLY bd CLI tool for task management - do not use your own task management tools
11658
- - Call whats_next() after the next user message to maintain the development workflow`;
11659
- return enhanced;
11660
- }
11661
- /**
11662
- * Generate beads-specific task management guidance
11663
- */
11664
- async generateBeadsCLIGuidance(context) {
11665
- const { instructionSource } = context;
11666
- if (instructionSource === "whats_next") {
11667
- let additionalInstructions = `**bd Task Management:**
11668
- `;
11669
- const phaseTaskId = await this.extractPhaseTaskId(context);
11670
- if (!phaseTaskId) {
11671
- return additionalInstructions + `- Use bd CLI tool exclusively
11672
- - **Start by listing ready tasks**: \`bd list --parent <phase-task-id> --status open\`
11673
- - **Create new tasks**: \`bd create 'Task title' --parent <phase-task-id> -p <priority>\`
11674
- - **Update status when working**: \`bd update <task-id> --status in_progress\`
11675
- - **Complete tasks**: \`bd close <task-id>\`
11676
- - **Focus on ready tasks first** - let beads handle dependencies
11677
- - Add new tasks as they are identified during your work with the user`;
11678
- }
11679
- return additionalInstructions + `
11680
- **Focus on subtasks of \`${phaseTaskId}\`**:
11681
- \u2022 \`bd list --parent ${phaseTaskId} --status open\` - List ready work items
11682
- \u2022 \`bd update <task-id> --status in_progress\` - Start working on a specific task
11683
- \u2022 \`bd close <task-id>\` - Mark task complete when finished
11684
-
11685
- **New Tasks for Current Phase**:
11686
- \u2022 \`bd create 'Task description' --parent ${phaseTaskId} -p <priority>\` - Create work item under current phase
11687
- \u2022 \`bd dep add <task-id> <depends-on-id>\` - Define dependencies for a task:`;
11688
- }
11689
- return "";
11690
- }
11691
- async extractPhaseTaskId(context) {
11692
- try {
11693
- const { readFile: readFile6 } = await import("fs/promises");
11694
- const content = await readFile6(
11695
- context.conversationContext.planFilePath,
11696
- "utf-8"
11697
- );
11698
- const phaseName = this.capitalizePhase(context.phase);
11699
- const phaseHeader = `## ${phaseName}`;
11700
- const phaseSection = content.split("\n");
11701
- let foundPhaseHeader = false;
11702
- for (const line of phaseSection) {
11703
- if (line.trim() === phaseHeader) {
11704
- foundPhaseHeader = true;
11705
- continue;
11706
- }
11707
- if (foundPhaseHeader && line.includes("beads-phase-id:")) {
11708
- const match = line.match(/beads-phase-id:\s*([\w\d.-]+)/);
11709
- if (match) {
11710
- return match[1] || null;
11711
- }
11712
- }
11713
- if (foundPhaseHeader && line.startsWith("##") && line !== phaseHeader) {
11714
- break;
11715
- }
11716
- }
11717
- return null;
11718
- } catch (_error) {
11719
- return null;
11720
- }
11721
- }
11722
- /**
11723
- * Capitalize phase name for display
11724
- */
11725
- capitalizePhase(phase) {
11726
- return phase.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
11727
- }
11728
- };
11729
- var logger24 = createLogger("ServerConfig");
11406
+ var logger15 = createLogger("ServerConfig");
11730
11407
  async function initializeServerComponents(config = {}) {
11731
- logger24.debug("Initializing server components", {
11408
+ logger15.debug("Initializing server components", {
11732
11409
  config: JSON.stringify(config)
11733
11410
  });
11734
11411
  const projectPath = normalizeProjectPath(
11735
11412
  config.projectPath || process.env.PROJECT_PATH
11736
11413
  );
11737
- logger24.info("Using project path", {
11414
+ logger15.info("Using project path", {
11738
11415
  projectPath,
11739
11416
  source: config.projectPath ? "config" : process.env.PROJECT_PATH ? "env" : "default"
11740
11417
  });
@@ -11751,11 +11428,11 @@ async function initializeServerComponents(config = {}) {
11751
11428
  );
11752
11429
  mcpServer.server.setRequestHandler(SetLevelRequestSchema, async (request) => {
11753
11430
  const level = request.params.level;
11754
- logger24.info("Setting logging level from MCP client", { level });
11755
- setMcpLoggingLevel(level);
11431
+ logger15.info("Setting logging level from MCP client", { level });
11432
+ setLoggingLevelFromString(level);
11756
11433
  return {};
11757
11434
  });
11758
- logger24.debug("Initializing core components");
11435
+ logger15.debug("Initializing core components");
11759
11436
  const database = new FileStorage(
11760
11437
  path4.join(projectPath, ".vibe", "conversation.sqlite")
11761
11438
  );
@@ -11768,38 +11445,31 @@ async function initializeServerComponents(config = {}) {
11768
11445
  const transitionEngine = new TransitionEngine(projectPath);
11769
11446
  transitionEngine.setConversationManager(conversationManager);
11770
11447
  const taskBackendConfig = TaskBackendManager.detectTaskBackend();
11771
- const isBeadsBackend = taskBackendConfig.backend === "beads" && taskBackendConfig.isAvailable;
11772
- logger24.info("Task backend configuration", {
11448
+ logger15.info("Task backend configuration", {
11773
11449
  backend: taskBackendConfig.backend,
11774
11450
  isAvailable: taskBackendConfig.isAvailable,
11775
11451
  autoDetected: !process.env["TASK_BACKEND"]
11776
11452
  });
11777
- const planManager = isBeadsBackend ? new BeadsPlanManager() : new PlanManager();
11778
- const instructionGenerator = isBeadsBackend ? new BeadsInstructionGenerator() : new InstructionGenerator(planManager);
11453
+ const planManager = new PlanManager();
11454
+ const instructionGenerator = new InstructionGenerator();
11779
11455
  const interactionLogger = new InteractionLogger(database);
11780
11456
  const pluginRegistry = new PluginRegistry();
11781
- if (process.env.COMMIT_BEHAVIOR) {
11782
- const commitPlugin = new CommitPlugin({ projectPath });
11783
- if (commitPlugin.isEnabled()) {
11784
- pluginRegistry.registerPlugin(commitPlugin);
11785
- logger24.info("CommitPlugin registered successfully", {
11786
- enabled: commitPlugin.isEnabled(),
11787
- sequence: commitPlugin.getSequence(),
11788
- behavior: process.env.COMMIT_BEHAVIOR
11789
- });
11790
- }
11791
- }
11792
- if (isBeadsBackend) {
11793
- const beadsPlugin = new BeadsPlugin({ projectPath });
11794
- if (beadsPlugin.isEnabled()) {
11795
- pluginRegistry.registerPlugin(beadsPlugin);
11796
- logger24.info("BeadsPlugin registered successfully", {
11797
- enabled: beadsPlugin.isEnabled(),
11798
- sequence: beadsPlugin.getSequence(),
11799
- autoDetected: !process.env["TASK_BACKEND"]
11800
- });
11801
- }
11802
- }
11457
+ const commitPlugin = new CommitPlugin({ projectPath });
11458
+ pluginRegistry.registerPlugin(commitPlugin);
11459
+ logger15.info("CommitPlugin registered", {
11460
+ enabled: commitPlugin.isEnabled(),
11461
+ sequence: commitPlugin.getSequence(),
11462
+ behavior: process.env.COMMIT_BEHAVIOR || "(not set)"
11463
+ });
11464
+ const beadsPlugin = new BeadsPlugin({ projectPath });
11465
+ pluginRegistry.registerPlugin(beadsPlugin);
11466
+ logger15.info("BeadsPlugin registered", {
11467
+ enabled: beadsPlugin.isEnabled(),
11468
+ sequence: beadsPlugin.getSequence(),
11469
+ backend: taskBackendConfig.backend,
11470
+ isAvailable: taskBackendConfig.isAvailable,
11471
+ autoDetected: !process.env["TASK_BACKEND"]
11472
+ });
11803
11473
  const context = {
11804
11474
  conversationManager,
11805
11475
  transitionEngine,
@@ -11812,7 +11482,7 @@ async function initializeServerComponents(config = {}) {
11812
11482
  };
11813
11483
  await database.initialize();
11814
11484
  workflowManager.loadProjectWorkflows(projectPath);
11815
- logger24.info("Server components initialized successfully");
11485
+ logger15.info("Server components initialized successfully");
11816
11486
  return {
11817
11487
  mcpServer,
11818
11488
  database,
@@ -11835,7 +11505,7 @@ function createToolHandler(toolName, toolRegistry, responseRenderer, context) {
11835
11505
  };
11836
11506
  }
11837
11507
  async function registerMcpTools(mcpServer, toolRegistry, responseRenderer, context) {
11838
- logger24.debug("Registering MCP tools");
11508
+ logger15.debug("Registering MCP tools");
11839
11509
  notificationService.setMcpServer(mcpServer);
11840
11510
  mcpServer.registerTool(
11841
11511
  "whats_next",
@@ -12035,7 +11705,7 @@ async function registerMcpTools(mcpServer, toolRegistry, responseRenderer, conte
12035
11705
  mcpServer.registerTool(
12036
11706
  "setup_project_docs",
12037
11707
  {
12038
- description: 'Create project documentation artifacts (architecture.md, requirements.md, design.md) using configurable templates OR by linking existing files via symlinks. **Linking existing documents Examples:**\n- `README.md` (project root)\n- `docs/architecture.md` (relative path)\n- `/absolute/path/to/requirements.txt`\n\n**Using "none" Option:**\n- Use `"none"` to create a placeholder that instructs LLM to use plan file instead\n- Useful when you prefer plan-file-only workflows\n\n**Mixed Usage Examples:**\n- `setup_project_docs({ architecture: "README.md", requirements: "none", design: "comprehensive" })`\n- `setup_project_docs({ architecture: "arc42", requirements: "ears", design: "none" })`',
11708
+ description: "Create or link project docs (architecture.md, requirements.md, design.md). Use template names or file paths.",
12039
11709
  inputSchema: {
12040
11710
  architecture: external_exports.string().default("freestyle").describe(
12041
11711
  `Architecture documentation: template name (${availableTemplates.architecture.join(", ")}, none) OR file path to existing document`
@@ -12082,12 +11752,12 @@ async function registerMcpTools(mcpServer, toolRegistry, responseRenderer, conte
12082
11752
  },
12083
11753
  createToolHandler("no_idea", toolRegistry, responseRenderer, context)
12084
11754
  );
12085
- logger24.info("MCP tools registered successfully", {
11755
+ logger15.info("MCP tools registered successfully", {
12086
11756
  tools: toolRegistry.list()
12087
11757
  });
12088
11758
  }
12089
11759
  function registerMcpResources(mcpServer, resourceRegistry, responseRenderer, context) {
12090
- logger24.debug("Registering MCP resources");
11760
+ logger15.debug("Registering MCP resources");
12091
11761
  mcpServer.resource(
12092
11762
  "Current Development Plan",
12093
11763
  "plan://current",
@@ -12220,7 +11890,7 @@ function registerMcpResources(mcpServer, resourceRegistry, responseRenderer, con
12220
11890
  };
12221
11891
  }
12222
11892
  );
12223
- logger24.info("MCP resources registered successfully", {
11893
+ logger15.info("MCP resources registered successfully", {
12224
11894
  resources: ["plan://current", "state://current", "system-prompt://"],
12225
11895
  resourceTemplates: ["workflow://{name}"]
12226
11896
  });
@@ -12235,18 +11905,22 @@ var BaseToolHandler = class {
12235
11905
  */
12236
11906
  async handle(args, context) {
12237
11907
  const handlerName = this.constructor.name;
12238
- logHandlerExecution(handlerName, args);
11908
+ if (context.loggerFactory) {
11909
+ this.logger = context.loggerFactory(handlerName);
11910
+ }
11911
+ logHandlerExecution(handlerName, args, this.logger);
12239
11912
  const result = await safeExecute(
12240
11913
  () => this.executeHandler(args, context),
12241
- `${handlerName} execution failed`
11914
+ `${handlerName} execution failed`,
11915
+ this.logger
12242
11916
  );
12243
11917
  if (!result.success && result.error?.includes("CONVERSATION_NOT_FOUND")) {
12244
11918
  const availableWorkflows = context.workflowManager.getWorkflowNames();
12245
11919
  const helpfulError = createConversationNotFoundResult(availableWorkflows);
12246
- logHandlerCompletion(handlerName, helpfulError);
11920
+ logHandlerCompletion(handlerName, helpfulError, this.logger);
12247
11921
  return helpfulError;
12248
11922
  }
12249
- logHandlerCompletion(handlerName, result);
11923
+ logHandlerCompletion(handlerName, result, this.logger);
12250
11924
  return result;
12251
11925
  }
12252
11926
  /**
@@ -12380,6 +12054,12 @@ var WhatsNextHandler = class extends ConversationRequiredToolHandler {
12380
12054
  const planInfo = await context.planManager.getPlanFileInfo(
12381
12055
  conversationContext.planFilePath
12382
12056
  );
12057
+ const stateMachine = context.workflowManager.loadWorkflowForProject(
12058
+ conversationContext.projectPath,
12059
+ conversationContext.workflowName
12060
+ );
12061
+ const phaseState = stateMachine.states[transitionResult.newPhase];
12062
+ const allowedFilePatterns = phaseState?.allowed_file_patterns ?? ["**/*"];
12383
12063
  const instructions = await context.instructionGenerator.generateInstructions(
12384
12064
  transitionResult.instructions,
12385
12065
  {
@@ -12390,14 +12070,40 @@ var WhatsNextHandler = class extends ConversationRequiredToolHandler {
12390
12070
  },
12391
12071
  transitionReason: transitionResult.transitionReason,
12392
12072
  isModeled: transitionResult.isModeled,
12393
- planFileExists: planInfo.exists,
12394
- instructionSource: "whats_next"
12073
+ instructionSource: "whats_next",
12074
+ allowedFilePatterns
12395
12075
  }
12396
12076
  );
12077
+ let finalInstructions = instructions.instructions;
12078
+ if (context.pluginRegistry?.hasHook("afterInstructionsGenerated")) {
12079
+ const hookContext = {
12080
+ conversationId,
12081
+ planFilePath: conversationContext.planFilePath,
12082
+ currentPhase: transitionResult.newPhase,
12083
+ workflow: conversationContext.workflowName,
12084
+ projectPath: conversationContext.projectPath,
12085
+ gitBranch: conversationContext.gitBranch,
12086
+ planFileExists: planInfo.exists
12087
+ };
12088
+ const enriched = await context.pluginRegistry.executeHook(
12089
+ "afterInstructionsGenerated",
12090
+ hookContext,
12091
+ {
12092
+ instructions: instructions.instructions,
12093
+ planFilePath: conversationContext.planFilePath,
12094
+ phase: transitionResult.newPhase,
12095
+ instructionSource: "whats_next"
12096
+ }
12097
+ );
12098
+ if (enriched && typeof enriched === "object" && "instructions" in enriched) {
12099
+ finalInstructions = enriched.instructions;
12100
+ }
12101
+ }
12397
12102
  const response = {
12398
12103
  phase: transitionResult.newPhase,
12399
- instructions: instructions.instructions,
12400
- plan_file_path: conversationContext.planFilePath
12104
+ instructions: finalInstructions,
12105
+ plan_file_path: conversationContext.planFilePath,
12106
+ allowed_file_patterns: allowedFilePatterns
12401
12107
  };
12402
12108
  await this.logInteraction(
12403
12109
  context,
@@ -12442,8 +12148,6 @@ var WhatsNextHandler = class extends ConversationRequiredToolHandler {
12442
12148
  }
12443
12149
  return true;
12444
12150
  }
12445
- // Beads-specific instruction logic has been moved to BeadsInstructionGenerator strategy
12446
- // Utility methods moved to strategy implementations where needed
12447
12151
  };
12448
12152
  var ProceedToPhaseHandler = class extends ConversationRequiredToolHandler {
12449
12153
  async executeWithConversation(args, context, conversationContext) {
@@ -12475,6 +12179,9 @@ var ProceedToPhaseHandler = class extends ConversationRequiredToolHandler {
12475
12179
  conversationContext.projectPath,
12476
12180
  context
12477
12181
  );
12182
+ const prePlanInfo = await context.planManager.getPlanFileInfo(
12183
+ conversationContext.planFilePath
12184
+ );
12478
12185
  const pluginContext = {
12479
12186
  conversationId,
12480
12187
  planFilePath: conversationContext.planFilePath,
@@ -12482,6 +12189,7 @@ var ProceedToPhaseHandler = class extends ConversationRequiredToolHandler {
12482
12189
  workflow: conversationContext.workflowName,
12483
12190
  projectPath: conversationContext.projectPath,
12484
12191
  gitBranch: conversationContext.gitBranch,
12192
+ planFileExists: prePlanInfo.exists,
12485
12193
  targetPhase: target_phase
12486
12194
  };
12487
12195
  if (context.pluginRegistry) {
@@ -12516,6 +12224,12 @@ var ProceedToPhaseHandler = class extends ConversationRequiredToolHandler {
12516
12224
  const planInfo = await context.planManager.getPlanFileInfo(
12517
12225
  conversationContext.planFilePath
12518
12226
  );
12227
+ const stateMachine = context.workflowManager.loadWorkflowForProject(
12228
+ conversationContext.projectPath,
12229
+ conversationContext.workflowName
12230
+ );
12231
+ const phaseState = stateMachine.states[transitionResult.newPhase];
12232
+ const allowedFilePatterns = phaseState?.allowed_file_patterns ?? ["**/*"];
12519
12233
  const instructions = await context.instructionGenerator.generateInstructions(
12520
12234
  transitionResult.instructions,
12521
12235
  {
@@ -12526,20 +12240,42 @@ var ProceedToPhaseHandler = class extends ConversationRequiredToolHandler {
12526
12240
  },
12527
12241
  transitionReason: transitionResult.transitionReason,
12528
12242
  isModeled: transitionResult.isModeled,
12529
- planFileExists: planInfo.exists,
12530
- instructionSource: "proceed_to_phase"
12243
+ instructionSource: "proceed_to_phase",
12244
+ allowedFilePatterns
12531
12245
  }
12532
12246
  );
12533
- instructions.instructions += `
12534
-
12535
- After transitioning to the ${transitionResult.newPhase} phase, check the already created tasks and add those that are missing based on the key decisions noted in the plan file.
12536
- While doing this, also denote dependencies for each task.
12537
- `;
12247
+ let finalInstructions = instructions.instructions;
12248
+ if (context.pluginRegistry?.hasHook("afterInstructionsGenerated")) {
12249
+ const hookContext = {
12250
+ conversationId,
12251
+ planFilePath: conversationContext.planFilePath,
12252
+ currentPhase: transitionResult.newPhase,
12253
+ workflow: conversationContext.workflowName,
12254
+ projectPath: conversationContext.projectPath,
12255
+ gitBranch: conversationContext.gitBranch,
12256
+ planFileExists: planInfo.exists
12257
+ };
12258
+ const enriched = await context.pluginRegistry.executeHook(
12259
+ "afterInstructionsGenerated",
12260
+ hookContext,
12261
+ {
12262
+ instructions: instructions.instructions,
12263
+ planFilePath: conversationContext.planFilePath,
12264
+ phase: transitionResult.newPhase,
12265
+ instructionSource: "proceed_to_phase"
12266
+ }
12267
+ );
12268
+ if (enriched && typeof enriched === "object" && "instructions" in enriched) {
12269
+ finalInstructions = enriched.instructions;
12270
+ }
12271
+ }
12272
+ finalInstructions += ` Review tasks for ${transitionResult.newPhase} phase, add missing ones based on key decisions.`;
12538
12273
  const response = {
12539
12274
  phase: transitionResult.newPhase,
12540
- instructions: instructions.instructions,
12275
+ instructions: finalInstructions,
12541
12276
  plan_file_path: conversationContext.planFilePath,
12542
- transition_reason: transitionResult.transitionReason
12277
+ transition_reason: transitionResult.transitionReason,
12278
+ allowed_file_patterns: allowedFilePatterns
12543
12279
  };
12544
12280
  await this.logInteraction(
12545
12281
  context,
@@ -12704,23 +12440,17 @@ var ConductReviewHandler = class extends ConversationRequiredToolHandler {
12704
12440
  * Generate instructions for LLM to conduct guided review
12705
12441
  */
12706
12442
  async generateReviewInstructions(perspectives, currentPhase, targetPhase) {
12707
- const instructions = `Conduct a review of the ${currentPhase} phase before proceeding to ${targetPhase}.
12708
-
12709
- First, identify the artifacts and decisions from the ${currentPhase} phase by:
12710
- 1. Reviewing the plan file to see completed tasks and key decisions
12711
- 2. Using git status/diff to see what files were changed (if in a git repository)
12712
- 3. Analyzing recent conversation history for important decisions
12443
+ const perspectiveDetails = perspectives.map(
12444
+ (p, i2) => `${i2 + 1}. **${p.perspective.toUpperCase()}**: ${p.prompt}`
12445
+ ).join("\n");
12446
+ const instructions = `Review ${currentPhase} phase before proceeding to ${targetPhase}.
12713
12447
 
12714
- Then, for each perspective below, analyze these artifacts and provide feedback:
12448
+ **Check:** plan file (tasks/decisions), git diff (changes), conversation history.
12715
12449
 
12716
- ${perspectives.map(
12717
- (p, i2) => `**${i2 + 1}. ${p.perspective.toUpperCase()} PERSPECTIVE:**
12718
- ${p.prompt}
12450
+ **Perspectives:**
12451
+ ${perspectiveDetails}
12719
12452
 
12720
- `
12721
- ).join("")}
12722
-
12723
- After completing all perspective reviews, summarize your findings and ask the user if they're ready to proceed to the ${targetPhase} phase.`;
12453
+ Summarize findings and ask user if ready to proceed.`;
12724
12454
  return {
12725
12455
  instructions,
12726
12456
  perspectives: perspectives.map((p) => ({
@@ -12730,16 +12460,19 @@ After completing all perspective reviews, summarize your findings and ask the us
12730
12460
  };
12731
12461
  }
12732
12462
  };
12733
- var logger25 = createLogger("StartDevelopmentHandler");
12734
12463
  var StartDevelopmentHandler = class extends BaseToolHandler {
12735
- projectDocsManager;
12736
- constructor() {
12737
- super();
12738
- this.projectDocsManager = new ProjectDocsManager();
12464
+ projectDocsManager = null;
12465
+ getProjectDocsManager() {
12466
+ if (!this.projectDocsManager) {
12467
+ this.projectDocsManager = new ProjectDocsManager(this.logger);
12468
+ }
12469
+ return this.projectDocsManager;
12739
12470
  }
12740
12471
  async executeHandler(args, context) {
12741
12472
  validateRequiredArgs(args, ["workflow"]);
12742
- const taskBackendConfig = TaskBackendManager.validateTaskBackend();
12473
+ const taskBackendConfig = TaskBackendManager.validateTaskBackend(
12474
+ this.logger
12475
+ );
12743
12476
  const selectedWorkflow = args.workflow;
12744
12477
  const requireReviews = args.require_reviews ?? false;
12745
12478
  const projectPath = stripVibePathSuffix(
@@ -12773,12 +12506,10 @@ var StartDevelopmentHandler = class extends BaseToolHandler {
12773
12506
  const suggestedBranchName = this.generateBranchSuggestion();
12774
12507
  const branchPromptResponse = {
12775
12508
  phase: "branch-prompt",
12776
- instructions: `You're currently on the ${currentBranch} branch. It's recommended to create a feature branch for development. Propose a branch creation by suggesting a branch command to the user call start_development again.
12777
-
12778
- Suggested command: \`git checkout -b ${suggestedBranchName}\`
12779
-
12780
- Please create a new branch and then call start_development again to begin development.`,
12781
- plan_file_path: ""
12509
+ instructions: `On ${currentBranch}. Create feature branch: \`git checkout -b ${suggestedBranchName}\`, then retry \`start_development\`.`,
12510
+ plan_file_path: "",
12511
+ allowed_file_patterns: ["**/*"]
12512
+ // Allow all files during branch prompt
12782
12513
  };
12783
12514
  this.logger.debug(
12784
12515
  "User on main/master branch, prompting for branch creation",
@@ -12836,6 +12567,8 @@ Please create a new branch and then call start_development again to begin develo
12836
12567
  workflow: selectedWorkflow,
12837
12568
  projectPath,
12838
12569
  gitBranch: conversationContext.gitBranch,
12570
+ planFileExists: true,
12571
+ // we just created/ensured the plan file exists
12839
12572
  stateMachine: {
12840
12573
  name: stateMachine.name,
12841
12574
  description: stateMachine.description,
@@ -12845,7 +12578,7 @@ Please create a new branch and then call start_development again to begin develo
12845
12578
  };
12846
12579
  if (context.pluginRegistry) {
12847
12580
  try {
12848
- const originalContent = await readFile5(
12581
+ const originalContent = await readFile4(
12849
12582
  conversationContext.planFilePath,
12850
12583
  "utf-8"
12851
12584
  );
@@ -12856,14 +12589,14 @@ Please create a new branch and then call start_development again to begin develo
12856
12589
  originalContent
12857
12590
  );
12858
12591
  if (modifiedContent && modifiedContent !== originalContent) {
12859
- await writeFile5(
12592
+ await writeFile4(
12860
12593
  conversationContext.planFilePath,
12861
12594
  modifiedContent,
12862
12595
  "utf-8"
12863
12596
  );
12864
12597
  }
12865
12598
  } catch (error) {
12866
- logger25.debug("Could not execute afterPlanFileCreated hook", {
12599
+ this.logger.debug("Could not execute afterPlanFileCreated hook", {
12867
12600
  error: error instanceof Error ? error.message : String(error),
12868
12601
  planFilePath: conversationContext.planFilePath
12869
12602
  });
@@ -12888,30 +12621,33 @@ Please create a new branch and then call start_development again to begin develo
12888
12621
  }
12889
12622
  this.ensureGitignoreEntry(projectPath);
12890
12623
  const workflowDocumentationUrl = this.generateWorkflowDocumentationUrl(selectedWorkflow);
12891
- const baseInstructions = `Look at the plan file (${conversationContext.planFilePath}). Define entrance criteria for each phase of the workflow except the initial phase. Those criteria shall be based on the contents of the previous phase.
12892
- Example:
12893
- \`\`\`
12894
- ## Design
12895
-
12896
- ### Phase Entrance Criteria:
12897
- - [ ] The requirements have been thoroughly defined.
12898
- - [ ] Alternatives have been evaluated and are documented.
12899
- - [ ] It's clear what's in scope and out of scope
12900
- \`\`\`
12901
-
12902
- IMPORTANT: Once you added reasonable entrance call the whats_next() tool to get guided instructions for the next current phase.`;
12903
- const i18nGuidance = `
12904
-
12905
- NOTE: If the user is communicating in a non-English language, please translate the plan file content to that language while keeping the structure intact, and continue all interactions in the user's language.`;
12906
- const workflowDocumentationInfo = workflowDocumentationUrl ? `
12907
-
12908
- Inform the user about the chose workflow: He can visit: ${workflowDocumentationUrl} to get detailed information.` : "";
12909
- const finalInstructions = baseInstructions + workflowDocumentationInfo + i18nGuidance;
12624
+ let finalInstructions = context.planManager.getInitialPlanGuidance(
12625
+ conversationContext.planFilePath,
12626
+ workflowDocumentationUrl
12627
+ );
12628
+ const phaseState = stateMachine.states[transitionResult.newPhase];
12629
+ const allowedFilePatterns = phaseState?.allowed_file_patterns ?? ["**/*"];
12630
+ if (context.pluginRegistry?.hasHook("afterInstructionsGenerated")) {
12631
+ const enriched = await context.pluginRegistry.executeHook(
12632
+ "afterInstructionsGenerated",
12633
+ pluginContext,
12634
+ {
12635
+ instructions: finalInstructions,
12636
+ planFilePath: conversationContext.planFilePath,
12637
+ phase: transitionResult.newPhase,
12638
+ instructionSource: "start_development"
12639
+ }
12640
+ );
12641
+ if (enriched && typeof enriched === "object" && "instructions" in enriched) {
12642
+ finalInstructions = enriched.instructions;
12643
+ }
12644
+ }
12910
12645
  const response = {
12911
12646
  phase: transitionResult.newPhase,
12912
12647
  instructions: finalInstructions,
12913
12648
  plan_file_path: conversationContext.planFilePath,
12914
- workflowDocumentationUrl
12649
+ workflowDocumentationUrl,
12650
+ allowed_file_patterns: allowedFilePatterns
12915
12651
  };
12916
12652
  await this.logInteraction(
12917
12653
  context,
@@ -12953,7 +12689,7 @@ Inform the user about the chose workflow: He can visit: ${workflowDocumentationU
12953
12689
  );
12954
12690
  return null;
12955
12691
  }
12956
- const docsInfo = await this.projectDocsManager.getProjectDocsInfo(projectPath);
12692
+ const docsInfo = await this.getProjectDocsManager().getProjectDocsInfo(projectPath);
12957
12693
  const missingDocs = this.getMissingReferencedDocuments(
12958
12694
  referencedVariables,
12959
12695
  docsInfo,
@@ -12971,9 +12707,7 @@ Inform the user about the chose workflow: He can visit: ${workflowDocumentationU
12971
12707
  }
12972
12708
  const setupGuidance = await this.generateArtifactSetupGuidance(
12973
12709
  missingDocs,
12974
- workflowName,
12975
- docsInfo,
12976
- referencedVariables
12710
+ workflowName
12977
12711
  );
12978
12712
  this.logger.info(
12979
12713
  "Missing required project artifacts detected for workflow that requires documentation",
@@ -12985,10 +12719,17 @@ Inform the user about the chose workflow: He can visit: ${workflowDocumentationU
12985
12719
  projectPath
12986
12720
  }
12987
12721
  );
12722
+ const initialPhase = stateMachine.initial_state;
12723
+ const initialPhaseState = stateMachine.states[initialPhase];
12724
+ const allowedFilePatterns = initialPhaseState?.allowed_file_patterns ?? [
12725
+ "**/*"
12726
+ ];
12988
12727
  return {
12989
12728
  phase: "artifact-setup",
12990
12729
  instructions: setupGuidance,
12991
- plan_file_path: ""
12730
+ plan_file_path: "",
12731
+ // Use the initial phase's file restrictions during artifact setup
12732
+ allowed_file_patterns: allowedFilePatterns
12992
12733
  };
12993
12734
  } catch (error) {
12994
12735
  this.logger.warn(
@@ -13005,7 +12746,7 @@ Inform the user about the chose workflow: He can visit: ${workflowDocumentationU
13005
12746
  * Analyze workflow content to detect document variable references
13006
12747
  */
13007
12748
  analyzeWorkflowDocumentReferences(stateMachine, projectPath) {
13008
- const variableSubstitutions = this.projectDocsManager.getVariableSubstitutions(projectPath);
12749
+ const variableSubstitutions = this.getProjectDocsManager().getVariableSubstitutions(projectPath);
13009
12750
  const documentVariables = Object.keys(variableSubstitutions);
13010
12751
  const referencedVariables = /* @__PURE__ */ new Set();
13011
12752
  const workflowContent = JSON.stringify(stateMachine);
@@ -13026,7 +12767,10 @@ Inform the user about the chose workflow: He can visit: ${workflowDocumentationU
13026
12767
  */
13027
12768
  getMissingReferencedDocuments(referencedVariables, docsInfo, projectPath) {
13028
12769
  const missingDocs = [];
13029
- const variableSubstitutions = this.projectDocsManager.getVariableSubstitutions(projectPath, void 0);
12770
+ const variableSubstitutions = this.getProjectDocsManager().getVariableSubstitutions(
12771
+ projectPath,
12772
+ void 0
12773
+ );
13030
12774
  const variableToDocMap = {};
13031
12775
  for (const [variable, path6] of Object.entries(variableSubstitutions)) {
13032
12776
  const filename = basename4(path6);
@@ -13047,115 +12791,15 @@ Inform the user about the chose workflow: He can visit: ${workflowDocumentationU
13047
12791
  /**
13048
12792
  * Generate guidance for setting up missing project artifacts
13049
12793
  */
13050
- async generateArtifactSetupGuidance(missingDocs, workflowName, docsInfo, referencedVariables) {
13051
- const missingList = missingDocs.map((doc) => `- ${doc}`).join("\n");
13052
- const existingDocs = [];
13053
- if (docsInfo.architecture.exists) {
13054
- const fileName = basename4(docsInfo.architecture.path);
13055
- existingDocs.push(`\u2705 ${fileName}`);
13056
- }
13057
- if (docsInfo.requirements.exists) {
13058
- const fileName = basename4(docsInfo.requirements.path);
13059
- existingDocs.push(`\u2705 ${fileName}`);
13060
- }
13061
- if (docsInfo.design.exists) {
13062
- const fileName = basename4(docsInfo.design.path);
13063
- existingDocs.push(`\u2705 ${fileName}`);
13064
- }
13065
- const existingList = existingDocs.length > 0 ? `
13066
-
13067
- **Existing Documents:**
13068
- ${existingDocs.join("\n")}` : "";
13069
- const referencedVariablesList = referencedVariables.map((v) => `\`${v}\``).join(", ");
13070
- const availableTemplates = await this.projectDocsManager.templateManager.getAvailableTemplates();
13071
- const defaults = await this.projectDocsManager.templateManager.getDefaults();
13072
- const templateOptionsText = this.generateTemplateOptionsText(availableTemplates);
13073
- return `## Project Documentation Setup Required
12794
+ async generateArtifactSetupGuidance(missingDocs, workflowName) {
12795
+ const availableTemplates = await this.getProjectDocsManager().templateManager.getAvailableTemplates();
12796
+ return `Missing docs for **${workflowName}**: ${missingDocs.join(", ")}
13074
12797
 
13075
- The **${workflowName}** workflow references project documentation that doesn't exist yet.
12798
+ Run \`setup_project_docs()\` with templates: ${Object.entries(
12799
+ availableTemplates
12800
+ ).map(([type2, templates]) => `${type2}: ${templates.join("/")}`).join("; ")}
13076
12801
 
13077
- **Referenced Variables:** ${referencedVariablesList}
13078
-
13079
- **Missing Documents:**
13080
- ${missingList}${existingList}
13081
-
13082
- ## \u{1F680} **Quick Setup**
13083
-
13084
- Use the \`setup_project_docs\` tool to create these documents with templates:
13085
-
13086
- \`\`\`
13087
- setup_project_docs({
13088
- architecture: "${defaults.architecture}", // or other available options
13089
- requirements: "${defaults.requirements}", // or other available options
13090
- design: "${defaults.design}" // or other available options
13091
- })
13092
- \`\`\`
13093
-
13094
- ${templateOptionsText}
13095
-
13096
- ## \u26A1 **Next Steps**
13097
-
13098
- 1. **Call \`setup_project_docs\`** with your preferred templates
13099
- 2. **Call \`start_development\`** again to begin the ${workflowName} workflow
13100
- 3. The workflow will reference these documents using the detected variables: ${referencedVariablesList}
13101
-
13102
- **Note:** You can also proceed without structured docs, but the workflow instructions will reference missing files.`;
13103
- }
13104
- /**
13105
- * Generate template options text dynamically
13106
- */
13107
- generateTemplateOptionsText(availableTemplates) {
13108
- const sections = [];
13109
- if (availableTemplates.architecture.length > 0) {
13110
- const archOptions = availableTemplates.architecture.map((template) => {
13111
- const description = this.getTemplateDescription(
13112
- template,
13113
- "architecture"
13114
- );
13115
- return `- **${template}**: ${description}`;
13116
- }).join("\n");
13117
- sections.push(`**Architecture Templates:**
13118
- ${archOptions}`);
13119
- }
13120
- if (availableTemplates.requirements.length > 0) {
13121
- const reqOptions = availableTemplates.requirements.map((template) => {
13122
- const description = this.getTemplateDescription(
13123
- template,
13124
- "requirements"
13125
- );
13126
- return `- **${template}**: ${description}`;
13127
- }).join("\n");
13128
- sections.push(`**Requirements Templates:**
13129
- ${reqOptions}`);
13130
- }
13131
- if (availableTemplates.design.length > 0) {
13132
- const designOptions = availableTemplates.design.map((template) => {
13133
- const description = this.getTemplateDescription(template, "design");
13134
- return `- **${template}**: ${description}`;
13135
- }).join("\n");
13136
- sections.push(`**Design Templates:**
13137
- ${designOptions}`);
13138
- }
13139
- return sections.length > 0 ? `## \u{1F4CB} **Template Options**
13140
-
13141
- ${sections.join("\n\n")}` : "";
13142
- }
13143
- /**
13144
- * Get description for a template based on its name and type
13145
- */
13146
- getTemplateDescription(template, type2) {
13147
- switch (template) {
13148
- case "arc42":
13149
- return "Comprehensive software architecture template with diagrams";
13150
- case "ears":
13151
- return "WHEN...THEN format for clear, testable requirements";
13152
- case "comprehensive":
13153
- return "Full implementation guide with testing strategy";
13154
- case "freestyle":
13155
- return `Simple, flexible ${type2} documentation`;
13156
- default:
13157
- return `${template} format for ${type2} documentation`;
13158
- }
12802
+ Then retry \`start_development\`.`;
13159
12803
  }
13160
12804
  /**
13161
12805
  * Generate workflow documentation URL for predefined workflows
@@ -13510,12 +13154,12 @@ var ResetDevelopmentHandler = class extends BaseToolHandler {
13510
13154
  return result;
13511
13155
  }
13512
13156
  };
13513
- var logger26 = createLogger("ListWorkflowsHandler");
13157
+ var logger16 = createLogger("ListWorkflowsHandler");
13514
13158
  var ListWorkflowsArgsSchema = external_exports.object({});
13515
13159
  var ListWorkflowsHandler = class extends BaseToolHandler {
13516
13160
  argsSchema = ListWorkflowsArgsSchema;
13517
13161
  async executeHandler(_args, context) {
13518
- logger26.info("Listing available workflows", {
13162
+ logger16.info("Listing available workflows", {
13519
13163
  projectPath: context.projectPath
13520
13164
  });
13521
13165
  const availableWorkflows = context.workflowManager.getAvailableWorkflowsForProject(
@@ -13530,18 +13174,18 @@ var ListWorkflowsHandler = class extends BaseToolHandler {
13530
13174
  const response = {
13531
13175
  workflows
13532
13176
  };
13533
- logger26.info("Successfully listed workflows", {
13177
+ logger16.info("Successfully listed workflows", {
13534
13178
  count: workflows.length,
13535
13179
  workflows: workflows.map((w) => w.name)
13536
13180
  });
13537
13181
  return response;
13538
13182
  }
13539
13183
  };
13540
- var logger27 = createLogger("VersionInfo");
13184
+ var logger17 = createLogger("VersionInfo");
13541
13185
  var BUILD_TIME_VERSION = null;
13542
13186
  function getVersionFromPackageJson() {
13543
13187
  try {
13544
- const currentDir = dirname7(fileURLToPath4(import.meta.url));
13188
+ const currentDir = dirname6(fileURLToPath4(import.meta.url));
13545
13189
  const packageJsonPaths = [
13546
13190
  join8(currentDir, "..", "package.json"),
13547
13191
  join8(currentDir, "..", "..", "..", "package.json")
@@ -13550,7 +13194,7 @@ function getVersionFromPackageJson() {
13550
13194
  try {
13551
13195
  const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
13552
13196
  if (packageJson.version) {
13553
- logger27.debug("Found version in package.json", {
13197
+ logger17.debug("Found version in package.json", {
13554
13198
  path: packageJsonPath,
13555
13199
  version: packageJson.version
13556
13200
  });
@@ -13560,7 +13204,7 @@ function getVersionFromPackageJson() {
13560
13204
  };
13561
13205
  }
13562
13206
  } catch (error) {
13563
- logger27.debug("Could not read package.json", {
13207
+ logger17.debug("Could not read package.json", {
13564
13208
  path: packageJsonPath,
13565
13209
  error: error instanceof Error ? error.message : String(error)
13566
13210
  });
@@ -13568,7 +13212,7 @@ function getVersionFromPackageJson() {
13568
13212
  }
13569
13213
  return null;
13570
13214
  } catch (error) {
13571
- logger27.debug("Error getting version from package.json", { error });
13215
+ logger17.debug("Error getting version from package.json", { error });
13572
13216
  return null;
13573
13217
  }
13574
13218
  }
@@ -13578,7 +13222,7 @@ function getVersionFromGit() {
13578
13222
  encoding: "utf-8",
13579
13223
  stdio: "pipe"
13580
13224
  }).trim();
13581
- logger27.debug("Git describe output", { gitDescribe });
13225
+ logger17.debug("Git describe output", { gitDescribe });
13582
13226
  const isDirty2 = gitDescribe.endsWith("-dirty");
13583
13227
  const cleanDescribe = isDirty2 ? gitDescribe.slice(0, -6) : gitDescribe;
13584
13228
  const parts = cleanDescribe.split("-");
@@ -13603,16 +13247,16 @@ function getVersionFromGit() {
13603
13247
  source: "git"
13604
13248
  };
13605
13249
  } catch (error) {
13606
- logger27.debug("Error getting version from git", {
13250
+ logger17.debug("Error getting version from git", {
13607
13251
  error: error instanceof Error ? error.message : String(error)
13608
13252
  });
13609
13253
  return null;
13610
13254
  }
13611
13255
  }
13612
13256
  function getVersionInfo() {
13613
- logger27.debug("Determining version information");
13257
+ logger17.debug("Determining version information");
13614
13258
  if (BUILD_TIME_VERSION) {
13615
- logger27.info("Using build-time version information", {
13259
+ logger17.info("Using build-time version information", {
13616
13260
  version: BUILD_TIME_VERSION.version,
13617
13261
  source: BUILD_TIME_VERSION.source
13618
13262
  });
@@ -13622,7 +13266,7 @@ function getVersionInfo() {
13622
13266
  if (gitVersion) {
13623
13267
  const packageVersion2 = getVersionFromPackageJson();
13624
13268
  if (packageVersion2 && gitVersion.version === "unknown") {
13625
- logger27.info("Using package.json version with git commit info", {
13269
+ logger17.info("Using package.json version with git commit info", {
13626
13270
  version: packageVersion2.version,
13627
13271
  commit: gitVersion.commit || "unknown",
13628
13272
  isDirty: String(gitVersion.isDirty || false)
@@ -13633,7 +13277,7 @@ function getVersionInfo() {
13633
13277
  source: "git"
13634
13278
  };
13635
13279
  }
13636
- logger27.info("Using git version information", {
13280
+ logger17.info("Using git version information", {
13637
13281
  version: gitVersion.version,
13638
13282
  source: gitVersion.source,
13639
13283
  commit: gitVersion.commit || "none",
@@ -13643,13 +13287,13 @@ function getVersionInfo() {
13643
13287
  }
13644
13288
  const packageVersion = getVersionFromPackageJson();
13645
13289
  if (packageVersion) {
13646
- logger27.info("Using package.json version information", {
13290
+ logger17.info("Using package.json version information", {
13647
13291
  version: packageVersion.version,
13648
13292
  source: packageVersion.source
13649
13293
  });
13650
13294
  return packageVersion;
13651
13295
  }
13652
- logger27.warn("Could not determine version information, using fallback");
13296
+ logger17.warn("Could not determine version information, using fallback");
13653
13297
  return {
13654
13298
  version: "unknown",
13655
13299
  source: "fallback"
@@ -13666,14 +13310,14 @@ function getFormattedVersion() {
13666
13310
  }
13667
13311
  return formatted;
13668
13312
  }
13669
- var logger28 = createLogger("GetToolInfoHandler");
13313
+ var logger18 = createLogger("GetToolInfoHandler");
13670
13314
  var GetToolInfoArgsSchema = external_exports.object({
13671
13315
  // No input parameters needed
13672
13316
  });
13673
13317
  var GetToolInfoHandler = class extends BaseToolHandler {
13674
13318
  argsSchema = GetToolInfoArgsSchema;
13675
13319
  async executeHandler(_args, context) {
13676
- logger28.info("Generating comprehensive tool information", {
13320
+ logger18.info("Generating comprehensive tool information", {
13677
13321
  projectPath: context.projectPath
13678
13322
  });
13679
13323
  const availableWorkflows = context.workflowManager.getAvailableWorkflowsForProject(
@@ -13763,7 +13407,7 @@ var GetToolInfoHandler = class extends BaseToolHandler {
13763
13407
  plan_file_path: conversationContext.planFilePath
13764
13408
  };
13765
13409
  } catch (error) {
13766
- logger28.debug("No active conversation found for workflow state", {
13410
+ logger18.debug("No active conversation found for workflow state", {
13767
13411
  error
13768
13412
  });
13769
13413
  }
@@ -13790,7 +13434,7 @@ var GetToolInfoHandler = class extends BaseToolHandler {
13790
13434
  if (workflowState) {
13791
13435
  response.workflow_states = workflowState;
13792
13436
  }
13793
- logger28.info("Successfully generated tool information", {
13437
+ logger18.info("Successfully generated tool information", {
13794
13438
  toolCount: tools.length,
13795
13439
  workflowCount: workflows.length,
13796
13440
  hasWorkflowState: !!workflowState
@@ -13808,22 +13452,25 @@ var GetToolInfoHandler = class extends BaseToolHandler {
13808
13452
  }
13809
13453
  };
13810
13454
  var SetupProjectDocsHandler = class extends BaseToolHandler {
13811
- projectDocsManager;
13812
- constructor() {
13813
- super();
13814
- this.projectDocsManager = new ProjectDocsManager();
13455
+ projectDocsManager = null;
13456
+ getProjectDocsManager() {
13457
+ if (!this.projectDocsManager) {
13458
+ this.projectDocsManager = new ProjectDocsManager(this.logger);
13459
+ }
13460
+ return this.projectDocsManager;
13815
13461
  }
13816
13462
  async executeHandler(args, context) {
13817
13463
  const projectPath = stripVibePathSuffix(
13818
13464
  args.project_path,
13819
13465
  context.projectPath || process.cwd()
13820
13466
  );
13467
+ const projectDocsManager = this.getProjectDocsManager();
13821
13468
  this.logger.info(
13822
13469
  "Setting up project docs with enhanced file linking support",
13823
13470
  { args, projectPath }
13824
13471
  );
13825
13472
  try {
13826
- const availableTemplates = await this.projectDocsManager.templateManager.getAvailableTemplates();
13473
+ const availableTemplates = await projectDocsManager.templateManager.getAvailableTemplates();
13827
13474
  const processedArgs = await this.validateAndProcessArgs(
13828
13475
  args,
13829
13476
  availableTemplates,
@@ -13835,7 +13482,7 @@ var SetupProjectDocsHandler = class extends BaseToolHandler {
13835
13482
  created: [],
13836
13483
  linked: [],
13837
13484
  skipped: [],
13838
- paths: this.projectDocsManager.getDocumentPaths(projectPath),
13485
+ paths: projectDocsManager.getDocumentPaths(projectPath),
13839
13486
  message: processedArgs.error || "Unknown error during validation"
13840
13487
  };
13841
13488
  }
@@ -13844,12 +13491,12 @@ var SetupProjectDocsHandler = class extends BaseToolHandler {
13844
13491
  "Invalid processed args: missing templateOptions or filePaths"
13845
13492
  );
13846
13493
  }
13847
- const result = await this.projectDocsManager.createOrLinkProjectDocs(
13494
+ const result = await projectDocsManager.createOrLinkProjectDocs(
13848
13495
  projectPath,
13849
13496
  processedArgs.templateOptions,
13850
13497
  processedArgs.filePaths
13851
13498
  );
13852
- const paths = this.projectDocsManager.getDocumentPaths(projectPath);
13499
+ const paths = projectDocsManager.getDocumentPaths(projectPath);
13853
13500
  let message = "Project documentation setup completed.";
13854
13501
  if (result.created.length > 0) {
13855
13502
  message += ` Created: ${result.created.join(", ")}.`;
@@ -13884,7 +13531,7 @@ var SetupProjectDocsHandler = class extends BaseToolHandler {
13884
13531
  created: [],
13885
13532
  linked: [],
13886
13533
  skipped: [],
13887
- paths: this.projectDocsManager.getDocumentPaths(projectPath),
13534
+ paths: projectDocsManager.getDocumentPaths(projectPath),
13888
13535
  message: `Failed to setup project docs: ${error instanceof Error ? error.message : "Unknown error"}`
13889
13536
  };
13890
13537
  }
@@ -13957,11 +13604,11 @@ var NoIdeaHandler = class extends BaseToolHandler {
13957
13604
  return { instructions };
13958
13605
  }
13959
13606
  };
13960
- var logger29 = createLogger("ToolRegistry");
13607
+ var logger19 = createLogger("ToolRegistry");
13961
13608
  var DefaultToolRegistry = class {
13962
13609
  handlers = /* @__PURE__ */ new Map();
13963
13610
  register(name, handler) {
13964
- logger29.debug("Registering tool handler", {
13611
+ logger19.debug("Registering tool handler", {
13965
13612
  name,
13966
13613
  handlerType: handler.constructor.name
13967
13614
  });
@@ -13986,15 +13633,22 @@ function createToolRegistry() {
13986
13633
  registry.register("get_tool_info", new GetToolInfoHandler());
13987
13634
  registry.register("setup_project_docs", new SetupProjectDocsHandler());
13988
13635
  registry.register("no_idea", new NoIdeaHandler());
13989
- logger29.info("Tool registry created with handlers", {
13636
+ logger19.info("Tool registry created with handlers", {
13990
13637
  handlers: registry.list()
13991
13638
  });
13992
13639
  return registry;
13993
13640
  }
13994
- var logger30 = createLogger("DevelopmentPlanResourceHandler");
13641
+ var defaultLogger8 = createLogger("DevelopmentPlanResourceHandler");
13995
13642
  var DevelopmentPlanResourceHandler = class {
13643
+ logger;
13644
+ constructor(logger24) {
13645
+ this.logger = logger24 ?? defaultLogger8;
13646
+ }
13996
13647
  async handle(uri, context) {
13997
- logger30.debug("Processing development plan resource request", {
13648
+ if (context.loggerFactory) {
13649
+ this.logger = context.loggerFactory("DevelopmentPlanResourceHandler");
13650
+ }
13651
+ this.logger.debug("Processing development plan resource request", {
13998
13652
  uri: uri.href
13999
13653
  });
14000
13654
  return safeExecute(async () => {
@@ -14010,10 +13664,17 @@ var DevelopmentPlanResourceHandler = class {
14010
13664
  }, "Failed to retrieve development plan resource");
14011
13665
  }
14012
13666
  };
14013
- var logger31 = createLogger("ConversationStateResourceHandler");
13667
+ var defaultLogger9 = createLogger("ConversationStateResourceHandler");
14014
13668
  var ConversationStateResourceHandler = class {
13669
+ logger;
13670
+ constructor(logger24) {
13671
+ this.logger = logger24 ?? defaultLogger9;
13672
+ }
14015
13673
  async handle(uri, context) {
14016
- logger31.debug("Processing conversation state resource request", {
13674
+ if (context.loggerFactory) {
13675
+ this.logger = context.loggerFactory("ConversationStateResourceHandler");
13676
+ }
13677
+ this.logger.debug("Processing conversation state resource request", {
14017
13678
  uri: uri.href
14018
13679
  });
14019
13680
  return safeExecute(async () => {
@@ -14035,10 +13696,19 @@ var ConversationStateResourceHandler = class {
14035
13696
  }, "Failed to retrieve conversation state resource");
14036
13697
  }
14037
13698
  };
14038
- var logger32 = createLogger("WorkflowResourceHandler");
13699
+ var defaultLogger10 = createLogger("WorkflowResourceHandler");
14039
13700
  var WorkflowResourceHandler = class {
13701
+ logger;
13702
+ constructor(logger24) {
13703
+ this.logger = logger24 ?? defaultLogger10;
13704
+ }
14040
13705
  async handle(uri, context) {
14041
- logger32.debug("Processing workflow resource request", { uri: uri.href });
13706
+ if (context.loggerFactory) {
13707
+ this.logger = context.loggerFactory("WorkflowResourceHandler");
13708
+ }
13709
+ this.logger.debug("Processing workflow resource request", {
13710
+ uri: uri.href
13711
+ });
14042
13712
  return safeExecute(async () => {
14043
13713
  const workflowName = uri.hostname;
14044
13714
  if (!workflowName) {
@@ -14046,7 +13716,10 @@ var WorkflowResourceHandler = class {
14046
13716
  "Invalid workflow URI: missing workflow name. Expected: workflow://workflow-name"
14047
13717
  );
14048
13718
  }
14049
- logger32.info("Loading workflow resource", { workflowName, uri: uri.href });
13719
+ this.logger.info("Loading workflow resource", {
13720
+ workflowName,
13721
+ uri: uri.href
13722
+ });
14050
13723
  let yamlContent;
14051
13724
  let filePath;
14052
13725
  const workflow = context.workflowManager.getWorkflow(workflowName);
@@ -14076,7 +13749,7 @@ var WorkflowResourceHandler = class {
14076
13749
  `${workflowName}.yml`
14077
13750
  );
14078
13751
  if (!fs5.existsSync(workflowFileYml)) {
14079
- logger32.error(
13752
+ this.logger.error(
14080
13753
  "Workflow file not found",
14081
13754
  new Error(`Workflow '${workflowName}' not found`),
14082
13755
  {
@@ -14100,7 +13773,7 @@ var WorkflowResourceHandler = class {
14100
13773
  filePath = workflowFile;
14101
13774
  }
14102
13775
  yamlContent = fs5.readFileSync(filePath, "utf-8");
14103
- logger32.info("Successfully loaded workflow resource", {
13776
+ this.logger.info("Successfully loaded workflow resource", {
14104
13777
  workflowName,
14105
13778
  filePath,
14106
13779
  contentLength: yamlContent.length
@@ -14113,17 +13786,24 @@ var WorkflowResourceHandler = class {
14113
13786
  }, `Failed to load workflow resource: ${uri.href}`);
14114
13787
  }
14115
13788
  };
14116
- var logger33 = createLogger("SystemPromptResourceHandler");
13789
+ var defaultLogger11 = createLogger("SystemPromptResourceHandler");
14117
13790
  var SystemPromptResourceHandler = class {
14118
- async handle(uri, _context) {
14119
- logger33.debug("Processing system prompt resource request", {
13791
+ logger;
13792
+ constructor(logger24) {
13793
+ this.logger = logger24 ?? defaultLogger11;
13794
+ }
13795
+ async handle(uri, context) {
13796
+ if (context.loggerFactory) {
13797
+ this.logger = context.loggerFactory("SystemPromptResourceHandler");
13798
+ }
13799
+ this.logger.debug("Processing system prompt resource request", {
14120
13800
  uri: uri.href
14121
13801
  });
14122
13802
  return safeExecute(async () => {
14123
13803
  const loader2 = new StateMachineLoader();
14124
13804
  const stateMachine = loader2.loadStateMachine(process.cwd());
14125
13805
  const systemPrompt = generateSystemPrompt(stateMachine);
14126
- logger33.debug("Generated system prompt for resource", {
13806
+ this.logger.debug("Generated system prompt for resource", {
14127
13807
  promptLength: systemPrompt.length,
14128
13808
  workflowName: stateMachine.name
14129
13809
  });
@@ -14135,11 +13815,11 @@ var SystemPromptResourceHandler = class {
14135
13815
  }, "Failed to retrieve system prompt resource");
14136
13816
  }
14137
13817
  };
14138
- var logger34 = createLogger("ResourceRegistry");
13818
+ var logger20 = createLogger("ResourceRegistry");
14139
13819
  var DefaultResourceRegistry = class {
14140
13820
  handlers = /* @__PURE__ */ new Map();
14141
13821
  register(pattern, handler) {
14142
- logger34.debug("Registering resource handler", {
13822
+ logger20.debug("Registering resource handler", {
14143
13823
  pattern,
14144
13824
  handlerType: handler.constructor.name
14145
13825
  });
@@ -14148,11 +13828,11 @@ var DefaultResourceRegistry = class {
14148
13828
  resolve(uri) {
14149
13829
  for (const [pattern, handler] of this.handlers.entries()) {
14150
13830
  if (uri.includes(pattern)) {
14151
- logger34.debug("Resolved resource handler", { uri, pattern });
13831
+ logger20.debug("Resolved resource handler", { uri, pattern });
14152
13832
  return handler;
14153
13833
  }
14154
13834
  }
14155
- logger34.debug("No resource handler found for URI", { uri });
13835
+ logger20.debug("No resource handler found for URI", { uri });
14156
13836
  return void 0;
14157
13837
  }
14158
13838
  };
@@ -14162,7 +13842,7 @@ function createResourceRegistry() {
14162
13842
  registry.register("state://current", new ConversationStateResourceHandler());
14163
13843
  registry.register("workflow://", new WorkflowResourceHandler());
14164
13844
  registry.register("system-prompt://", new SystemPromptResourceHandler());
14165
- logger34.info("Resource registry created with handlers", {
13845
+ logger20.info("Resource registry created with handlers", {
14166
13846
  patterns: [
14167
13847
  "plan://current",
14168
13848
  "state://current",
@@ -14172,13 +13852,13 @@ function createResourceRegistry() {
14172
13852
  });
14173
13853
  return registry;
14174
13854
  }
14175
- var logger35 = createLogger("ResponseRenderer");
13855
+ var logger21 = createLogger("ResponseRenderer");
14176
13856
  var DefaultResponseRenderer = class {
14177
13857
  /**
14178
13858
  * Render a tool handler result as an MCP tool response
14179
13859
  */
14180
13860
  renderToolResponse(result) {
14181
- logger35.debug("Rendering tool response", {
13861
+ logger21.debug("Rendering tool response", {
14182
13862
  success: result.success,
14183
13863
  hasData: !!result.data,
14184
13864
  hasError: !!result.error
@@ -14200,7 +13880,7 @@ var DefaultResponseRenderer = class {
14200
13880
  * Render a resource handler result as an MCP resource response
14201
13881
  */
14202
13882
  renderResourceResponse(result) {
14203
- logger35.debug("Rendering resource response", {
13883
+ logger21.debug("Rendering resource response", {
14204
13884
  success: result.success,
14205
13885
  hasData: !!result.data
14206
13886
  });
@@ -14231,7 +13911,7 @@ var DefaultResponseRenderer = class {
14231
13911
  */
14232
13912
  renderError(error) {
14233
13913
  const errorMessage = error instanceof Error ? error.message : error;
14234
- logger35.debug("Rendering error response", { errorMessage });
13914
+ logger21.debug("Rendering error response", { errorMessage });
14235
13915
  return {
14236
13916
  content: [
14237
13917
  {
@@ -14246,7 +13926,50 @@ var DefaultResponseRenderer = class {
14246
13926
  function createResponseRenderer() {
14247
13927
  return new DefaultResponseRenderer();
14248
13928
  }
14249
- var logger36 = createLogger("ResponsibleVibeMCPServer");
13929
+ function capitalizePhase2(phase) {
13930
+ return phase.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
13931
+ }
13932
+ function createMcpLogSink(mcpServer) {
13933
+ return {
13934
+ async log(level, logger24, message, context) {
13935
+ try {
13936
+ let enhancedMessage = message;
13937
+ let notificationLevel = level;
13938
+ if (context && (context["from"] || context["to"]) && message.includes("transition")) {
13939
+ const from = context["from"] ? capitalizePhase2(context["from"]) : "";
13940
+ const to = context["to"] ? capitalizePhase2(context["to"]) : "";
13941
+ if (from && to) {
13942
+ enhancedMessage = `Phase Transition: ${from} \u2192 ${to}`;
13943
+ notificationLevel = "info";
13944
+ }
13945
+ }
13946
+ if (message.includes("initialized successfully")) {
13947
+ enhancedMessage = "\u{1F680} Vibe Feature MCP Server Ready";
13948
+ notificationLevel = "info";
13949
+ }
13950
+ let logData = enhancedMessage;
13951
+ if (context) {
13952
+ try {
13953
+ const contextStr = JSON.stringify(context, null, 0);
13954
+ logData = `${enhancedMessage} ${contextStr}`;
13955
+ } catch (_error) {
13956
+ logData = `${enhancedMessage} [context serialization failed]`;
13957
+ }
13958
+ }
13959
+ await mcpServer.server.notification({
13960
+ method: "notifications/message",
13961
+ params: {
13962
+ level: notificationLevel,
13963
+ logger: logger24,
13964
+ data: logData
13965
+ }
13966
+ });
13967
+ } catch (_error) {
13968
+ }
13969
+ }
13970
+ };
13971
+ }
13972
+ var logger22 = createLogger("ResponsibleVibeMCPServer");
14250
13973
  async function createResponsibleVibeMCPServer(config = {}) {
14251
13974
  const components = await initializeServerComponents(config);
14252
13975
  return new ResponsibleVibeMCPServer(config, components);
@@ -14255,7 +13978,7 @@ var ResponsibleVibeMCPServer = class {
14255
13978
  constructor(config, serverComponents) {
14256
13979
  this.config = config;
14257
13980
  this.serverComponents = serverComponents;
14258
- logger36.debug("ResponsibleVibeMCPServer created", {
13981
+ logger22.debug("ResponsibleVibeMCPServer created", {
14259
13982
  config: JSON.stringify(this.config)
14260
13983
  });
14261
13984
  }
@@ -14264,7 +13987,7 @@ var ResponsibleVibeMCPServer = class {
14264
13987
  * Initialize the server and all its components
14265
13988
  */
14266
13989
  async initialize() {
14267
- logger36.debug("Initializing ResponsibleVibeMCPServer");
13990
+ logger22.debug("Initializing ResponsibleVibeMCPServer");
14268
13991
  try {
14269
13992
  this.components = this.serverComponents;
14270
13993
  const toolRegistry = createToolRegistry();
@@ -14273,7 +13996,7 @@ var ResponsibleVibeMCPServer = class {
14273
13996
  this.components.toolRegistry = toolRegistry;
14274
13997
  this.components.resourceRegistry = resourceRegistry;
14275
13998
  this.components.responseRenderer = responseRenderer;
14276
- setMcpServerForLogging(this.components.mcpServer);
13999
+ registerLogSink(createMcpLogSink(this.components.mcpServer));
14277
14000
  await registerMcpTools(
14278
14001
  this.components.mcpServer,
14279
14002
  toolRegistry,
@@ -14287,7 +14010,7 @@ var ResponsibleVibeMCPServer = class {
14287
14010
  this.components.context
14288
14011
  );
14289
14012
  } catch (error) {
14290
- logger36.error(
14013
+ logger22.error(
14291
14014
  "Failed to initialize ResponsibleVibeMCPServer",
14292
14015
  error
14293
14016
  );
@@ -14420,14 +14143,14 @@ var ResponsibleVibeMCPServer = class {
14420
14143
  * Cleanup server resources
14421
14144
  */
14422
14145
  async cleanup() {
14423
- logger36.debug("Cleaning up server resources");
14146
+ logger22.debug("Cleaning up server resources");
14424
14147
  if (this.components?.database) {
14425
14148
  await this.components.database.close();
14426
14149
  }
14427
- logger36.info("Server cleanup completed");
14150
+ logger22.info("Server cleanup completed");
14428
14151
  }
14429
14152
  };
14430
- var logger37 = createLogger("Main");
14153
+ var logger23 = createLogger("Main");
14431
14154
  function parseCliArgs() {
14432
14155
  return { shouldStartServer: true };
14433
14156
  }
@@ -14445,30 +14168,46 @@ async function main() {
14445
14168
  const transport = new StdioServerTransport();
14446
14169
  await server.getMcpServer().connect(transport);
14447
14170
  process.on("SIGINT", async () => {
14448
- logger37.info("Shutting down Vibe Feature MCP Server...");
14171
+ logger23.info("Shutting down Vibe Feature MCP Server...");
14449
14172
  await server.cleanup();
14450
14173
  process.exit(0);
14451
14174
  });
14452
14175
  process.on("SIGTERM", async () => {
14453
- logger37.info("Shutting down Vibe Feature MCP Server...");
14176
+ logger23.info("Shutting down Vibe Feature MCP Server...");
14454
14177
  await server.cleanup();
14455
14178
  process.exit(0);
14456
14179
  });
14457
14180
  } catch (error) {
14458
- logger37.error("Failed to start server", error);
14181
+ logger23.error("Failed to start server", error);
14459
14182
  process.exit(1);
14460
14183
  }
14461
14184
  }
14462
14185
  var isMainModule = import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith("ade-workflows-server") || process.argv[1]?.endsWith("index.js");
14463
14186
  if (isMainModule) {
14464
14187
  await main().catch((error) => {
14465
- logger37.error("Unhandled error in main", error);
14188
+ logger23.error("Unhandled error in main", error);
14466
14189
  process.exit(1);
14467
14190
  });
14468
14191
  }
14469
14192
  export {
14193
+ BaseToolHandler,
14194
+ BeadsPlugin,
14195
+ ConductReviewHandler,
14196
+ ConversationRequiredToolHandler,
14197
+ DefaultToolRegistry,
14198
+ GetToolInfoHandler,
14199
+ ListWorkflowsHandler,
14200
+ NoIdeaHandler,
14201
+ PluginRegistry,
14202
+ ProceedToPhaseHandler,
14203
+ ResetDevelopmentHandler,
14470
14204
  ResponsibleVibeMCPServer,
14205
+ ResumeWorkflowHandler,
14206
+ SetupProjectDocsHandler,
14207
+ StartDevelopmentHandler,
14208
+ WhatsNextHandler,
14471
14209
  createResponsibleVibeMCPServer,
14210
+ createToolRegistry,
14472
14211
  main as startMcpServer
14473
14212
  };
14474
14213
  /*! Bundled license information: