@codemcp/workflows 6.7.0 → 6.9.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.
@@ -12540,16 +12540,20 @@ var EMPTY_COMPLETION_RESULT = {
12540
12540
  // ../mcp-server/dist/index.js
12541
12541
  import * as path4 from "path";
12542
12542
  import { homedir } from "os";
12543
+ import { watch } from "fs";
12544
+ import { join as join8 } from "path";
12543
12545
  import { execSync as execSync5 } from "child_process";
12546
+ import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
12547
+ import { join as join7 } from "path";
12544
12548
  import { basename as basename4 } from "path";
12545
12549
  import { readFileSync, writeFileSync, existsSync as existsSync3, mkdirSync } from "fs";
12546
- import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
12550
+ import { readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
12547
12551
  import { resolve as resolve3 } from "path";
12548
12552
  import { z as z22 } from "zod";
12549
12553
  import { z as z3 } from "zod";
12550
12554
  import { execSync as execSync6 } from "child_process";
12551
12555
  import { readFileSync as readFileSync2 } from "fs";
12552
- import { join as join8, dirname as dirname6 } from "path";
12556
+ import { join as join10, dirname as dirname6 } from "path";
12553
12557
  import { fileURLToPath as fileURLToPath4 } from "url";
12554
12558
  import { z as z4 } from "zod";
12555
12559
  import fs5 from "fs";
@@ -19116,6 +19120,112 @@ var BeadsTaskBackendClient = class {
19116
19120
  }
19117
19121
  }
19118
19122
  };
19123
+ var defaultLogger8 = createLogger("BeadsPlanSyncer");
19124
+ var BeadsPlanSyncer = class {
19125
+ logger;
19126
+ constructor(logger242) {
19127
+ this.logger = logger242 ?? defaultLogger8;
19128
+ }
19129
+ /**
19130
+ * Sync the given plan file with the latest beads tasks.
19131
+ *
19132
+ * No-ops when the plan file doesn't exist yet, when no phase IDs are
19133
+ * resolved, or when .beads/issues.jsonl is absent. Never throws.
19134
+ */
19135
+ async sync(planFilePath, projectPath) {
19136
+ try {
19137
+ const issues = await this.readIssues(projectPath);
19138
+ if (issues === null) {
19139
+ return;
19140
+ }
19141
+ let planContent;
19142
+ try {
19143
+ planContent = await readFile4(planFilePath, "utf-8");
19144
+ } catch (err) {
19145
+ if (err.code === "ENOENT") return;
19146
+ throw err;
19147
+ }
19148
+ const updated = this.updatePlanContent(planContent, issues);
19149
+ if (updated !== planContent) {
19150
+ await writeFile4(planFilePath, updated, "utf-8");
19151
+ this.logger.debug("Plan file synced with beads tasks", {
19152
+ planFilePath
19153
+ });
19154
+ }
19155
+ } catch (error) {
19156
+ this.logger.warn("BeadsPlanSyncer: sync failed", {
19157
+ error: error instanceof Error ? error.message : String(error),
19158
+ planFilePath,
19159
+ projectPath
19160
+ });
19161
+ }
19162
+ }
19163
+ /**
19164
+ * Read and parse .beads/issues.jsonl.
19165
+ * Returns null if the file doesn't exist.
19166
+ */
19167
+ async readIssues(projectPath) {
19168
+ const jsonlPath = join7(projectPath, ".beads", "issues.jsonl");
19169
+ let raw;
19170
+ try {
19171
+ raw = await readFile4(jsonlPath, "utf-8");
19172
+ } catch (err) {
19173
+ if (err.code === "ENOENT") return null;
19174
+ throw err;
19175
+ }
19176
+ const issues = [];
19177
+ for (const line of raw.split("\n")) {
19178
+ const trimmed = line.trim();
19179
+ if (!trimmed) continue;
19180
+ try {
19181
+ issues.push(JSON.parse(trimmed));
19182
+ } catch {
19183
+ }
19184
+ }
19185
+ return issues;
19186
+ }
19187
+ /**
19188
+ * Find direct children of a given phase task ID.
19189
+ * A child issue has a parent-child dependency pointing to phaseId.
19190
+ */
19191
+ getChildTasks(issues, phaseId) {
19192
+ return issues.filter(
19193
+ (issue) => issue.dependencies?.some(
19194
+ (dep) => dep.depends_on_id === phaseId && dep.type === "parent-child"
19195
+ )
19196
+ );
19197
+ }
19198
+ /**
19199
+ * Rewrite all synced task sections in the plan content.
19200
+ */
19201
+ updatePlanContent(content, issues) {
19202
+ const phaseSectionRe = /(## [^\n]+\n<!-- beads-phase-id: (?!TBD)([^\s>]+) -->)([\s\S]*?)(### Tasks\n)([\s\S]*?)(?=\n## |\n### |$)/g;
19203
+ return content.replace(
19204
+ phaseSectionRe,
19205
+ (_match, phaseHeaderAndId, phaseId, betweenIdAndTasks, tasksHeader, _existingBody) => {
19206
+ const children = this.getChildTasks(issues, phaseId);
19207
+ const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
19208
+ const header = `<!-- beads-synced: ${today} -->
19209
+ *Auto-synced \u2014 do not edit here, use \`bd\` CLI instead.*
19210
+ `;
19211
+ let tasksBody;
19212
+ if (children.length === 0) {
19213
+ tasksBody = `${header}
19214
+ `;
19215
+ } else {
19216
+ const taskLines = children.map((task) => {
19217
+ const checkbox = task.status === "closed" ? "[x]" : "[ ]";
19218
+ return `- ${checkbox} \`${task.id}\` ${task.title}`;
19219
+ }).join("\n");
19220
+ tasksBody = `${header}
19221
+ ${taskLines}
19222
+ `;
19223
+ }
19224
+ return `${phaseHeaderAndId}${betweenIdAndTasks}${tasksHeader}${tasksBody}`;
19225
+ }
19226
+ );
19227
+ }
19228
+ };
19119
19229
  var BeadsPlugin = class {
19120
19230
  projectPath;
19121
19231
  beadsStateManager;
@@ -19123,6 +19233,17 @@ var BeadsPlugin = class {
19123
19233
  planManager;
19124
19234
  logger;
19125
19235
  loggerFactory;
19236
+ planSyncer;
19237
+ /**
19238
+ * Plan file path captured from the most recent hook context.
19239
+ * Set by afterStartDevelopment and beforePhaseTransition so the watcher
19240
+ * always has the correct path without touching GitManager.
19241
+ */
19242
+ activePlanFilePath = null;
19243
+ /** Debounce timer for the JSONL file watcher */
19244
+ syncDebounceTimer = null;
19245
+ /** Active fs.watch watcher (closed on process exit) */
19246
+ jsonlWatcher = null;
19126
19247
  constructor(options) {
19127
19248
  this.projectPath = options.projectPath;
19128
19249
  this.loggerFactory = options.loggerFactory;
@@ -19136,6 +19257,13 @@ var BeadsPlugin = class {
19136
19257
  options.loggerFactory ? options.loggerFactory("BeadsTaskBackendClient") : void 0
19137
19258
  );
19138
19259
  this.planManager = new PlanManager();
19260
+ this.planSyncer = new BeadsPlanSyncer(
19261
+ options.loggerFactory ? options.loggerFactory("BeadsPlanSyncer") : void 0
19262
+ );
19263
+ process.once("exit", () => {
19264
+ this.jsonlWatcher?.close();
19265
+ });
19266
+ this.startJsonlWatcher();
19139
19267
  this.logger.debug("BeadsPlugin initialized", {
19140
19268
  projectPath: this.projectPath
19141
19269
  });
@@ -19170,6 +19298,7 @@ var BeadsPlugin = class {
19170
19298
  * Replaces validateBeadsTaskCompletion() method from proceed-to-phase.ts
19171
19299
  */
19172
19300
  async handleBeforePhaseTransition(context, currentPhase, targetPhase) {
19301
+ this.activePlanFilePath = context.planFilePath;
19173
19302
  this.logger.info(
19174
19303
  "BeadsPlugin: Validating task completion before phase transition",
19175
19304
  {
@@ -19212,6 +19341,7 @@ var BeadsPlugin = class {
19212
19341
  * Implements graceful degradation: continues app operation even if beads operations fail
19213
19342
  */
19214
19343
  async handleAfterStartDevelopment(context, args, _result) {
19344
+ this.activePlanFilePath = context.planFilePath;
19215
19345
  this.logger.info("BeadsPlugin: Setting up beads integration", {
19216
19346
  conversationId: context.conversationId,
19217
19347
  workflow: args.workflow,
@@ -19447,8 +19577,8 @@ Complete tasks: \`bd close <id>\``;
19447
19577
  */
19448
19578
  async extractPhaseTaskIdFromPlanFile(planFilePath, phase) {
19449
19579
  try {
19450
- const { readFile: readFile52 } = await import("fs/promises");
19451
- const content = await readFile52(planFilePath, "utf-8");
19580
+ const { readFile: readFile62 } = await import("fs/promises");
19581
+ const content = await readFile62(planFilePath, "utf-8");
19452
19582
  const phaseName = this.capitalizePhase(phase);
19453
19583
  const phaseHeader = `## ${phaseName}`;
19454
19584
  const lines = content.split("\n");
@@ -19602,6 +19732,40 @@ Complete tasks: \`bd close <id>\``;
19602
19732
  );
19603
19733
  }
19604
19734
  }
19735
+ /**
19736
+ * Start watching the .beads/ directory for changes to issues.jsonl.
19737
+ * Watching the directory (not the file) means the watcher works even when
19738
+ * issues.jsonl doesn't exist yet. On change, debounces 300ms then syncs.
19739
+ */
19740
+ startJsonlWatcher() {
19741
+ const beadsDir = join8(this.projectPath, ".beads");
19742
+ try {
19743
+ this.jsonlWatcher = watch(beadsDir, (_event, filename) => {
19744
+ if (filename !== "issues.jsonl") return;
19745
+ if (this.syncDebounceTimer) {
19746
+ clearTimeout(this.syncDebounceTimer);
19747
+ }
19748
+ this.syncDebounceTimer = setTimeout(() => {
19749
+ this.syncDebounceTimer = null;
19750
+ if (!this.activePlanFilePath) return;
19751
+ this.planSyncer.sync(this.activePlanFilePath, this.projectPath).catch((err) => {
19752
+ this.logger.warn(
19753
+ "BeadsPlugin: Error during watcher-triggered plan sync",
19754
+ {
19755
+ error: err instanceof Error ? err.message : String(err)
19756
+ }
19757
+ );
19758
+ });
19759
+ }, 300);
19760
+ });
19761
+ this.logger.info("BeadsPlugin: Started JSONL file watcher", { beadsDir });
19762
+ } catch (error) {
19763
+ this.logger.warn("BeadsPlugin: Could not start JSONL file watcher", {
19764
+ error: error instanceof Error ? error.message : String(error),
19765
+ beadsDir
19766
+ });
19767
+ }
19768
+ }
19605
19769
  /**
19606
19770
  * Extract Goal section content from plan file
19607
19771
  * Returns the goal content if it exists and is meaningful, otherwise undefined
@@ -19643,10 +19807,10 @@ Complete tasks: \`bd close <id>\``;
19643
19807
  */
19644
19808
  async updatePlanFileWithPhaseTaskIds(planFilePath, phaseTasks) {
19645
19809
  try {
19646
- const { readFile: readFile52, writeFile: writeFile52 } = await import("fs/promises");
19810
+ const { readFile: readFile62, writeFile: writeFile62 } = await import("fs/promises");
19647
19811
  let content;
19648
19812
  try {
19649
- content = await readFile52(planFilePath, "utf-8");
19813
+ content = await readFile62(planFilePath, "utf-8");
19650
19814
  } catch (error) {
19651
19815
  const errorMsg = error instanceof Error ? error.message : String(error);
19652
19816
  this.logger.warn("BeadsPlugin: Failed to read plan file for update", {
@@ -19679,7 +19843,7 @@ Complete tasks: \`bd close <id>\``;
19679
19843
  );
19680
19844
  }
19681
19845
  try {
19682
- await writeFile52(planFilePath, content, "utf-8");
19846
+ await writeFile62(planFilePath, content, "utf-8");
19683
19847
  } catch (error) {
19684
19848
  const errorMsg = error instanceof Error ? error.message : String(error);
19685
19849
  this.logger.warn("BeadsPlugin: Failed to write updated plan file", {
@@ -21058,7 +21222,7 @@ var StartDevelopmentHandler = class extends BaseToolHandler {
21058
21222
  };
21059
21223
  if (context.pluginRegistry) {
21060
21224
  try {
21061
- const originalContent = await readFile4(
21225
+ const originalContent = await readFile5(
21062
21226
  conversationContext.planFilePath,
21063
21227
  "utf-8"
21064
21228
  );
@@ -21069,7 +21233,7 @@ var StartDevelopmentHandler = class extends BaseToolHandler {
21069
21233
  originalContent
21070
21234
  );
21071
21235
  if (modifiedContent && modifiedContent !== originalContent) {
21072
- await writeFile4(
21236
+ await writeFile5(
21073
21237
  conversationContext.planFilePath,
21074
21238
  modifiedContent,
21075
21239
  "utf-8"
@@ -21667,8 +21831,8 @@ function getVersionFromPackageJson() {
21667
21831
  try {
21668
21832
  const currentDir = dirname6(fileURLToPath4(import.meta.url));
21669
21833
  const packageJsonPaths = [
21670
- join8(currentDir, "..", "package.json"),
21671
- join8(currentDir, "..", "..", "..", "package.json")
21834
+ join10(currentDir, "..", "package.json"),
21835
+ join10(currentDir, "..", "..", "..", "package.json")
21672
21836
  ];
21673
21837
  for (const packageJsonPath of packageJsonPaths) {
21674
21838
  try {
@@ -22118,11 +22282,11 @@ function createToolRegistry() {
22118
22282
  });
22119
22283
  return registry;
22120
22284
  }
22121
- var defaultLogger8 = createLogger("DevelopmentPlanResourceHandler");
22285
+ var defaultLogger9 = createLogger("DevelopmentPlanResourceHandler");
22122
22286
  var DevelopmentPlanResourceHandler = class {
22123
22287
  logger;
22124
22288
  constructor(logger242) {
22125
- this.logger = logger242 ?? defaultLogger8;
22289
+ this.logger = logger242 ?? defaultLogger9;
22126
22290
  }
22127
22291
  async handle(uri, context) {
22128
22292
  if (context.loggerFactory) {
@@ -22144,11 +22308,11 @@ var DevelopmentPlanResourceHandler = class {
22144
22308
  }, "Failed to retrieve development plan resource");
22145
22309
  }
22146
22310
  };
22147
- var defaultLogger9 = createLogger("ConversationStateResourceHandler");
22311
+ var defaultLogger10 = createLogger("ConversationStateResourceHandler");
22148
22312
  var ConversationStateResourceHandler = class {
22149
22313
  logger;
22150
22314
  constructor(logger242) {
22151
- this.logger = logger242 ?? defaultLogger9;
22315
+ this.logger = logger242 ?? defaultLogger10;
22152
22316
  }
22153
22317
  async handle(uri, context) {
22154
22318
  if (context.loggerFactory) {
@@ -22176,11 +22340,11 @@ var ConversationStateResourceHandler = class {
22176
22340
  }, "Failed to retrieve conversation state resource");
22177
22341
  }
22178
22342
  };
22179
- var defaultLogger10 = createLogger("WorkflowResourceHandler");
22343
+ var defaultLogger11 = createLogger("WorkflowResourceHandler");
22180
22344
  var WorkflowResourceHandler = class {
22181
22345
  logger;
22182
22346
  constructor(logger242) {
22183
- this.logger = logger242 ?? defaultLogger10;
22347
+ this.logger = logger242 ?? defaultLogger11;
22184
22348
  }
22185
22349
  async handle(uri, context) {
22186
22350
  if (context.loggerFactory) {
@@ -22266,11 +22430,11 @@ var WorkflowResourceHandler = class {
22266
22430
  }, `Failed to load workflow resource: ${uri.href}`);
22267
22431
  }
22268
22432
  };
22269
- var defaultLogger11 = createLogger("SystemPromptResourceHandler");
22433
+ var defaultLogger12 = createLogger("SystemPromptResourceHandler");
22270
22434
  var SystemPromptResourceHandler = class {
22271
22435
  logger;
22272
22436
  constructor(logger242) {
22273
- this.logger = logger242 ?? defaultLogger11;
22437
+ this.logger = logger242 ?? defaultLogger12;
22274
22438
  }
22275
22439
  async handle(uri, context) {
22276
22440
  if (context.loggerFactory) {
@@ -26174,12 +26338,12 @@ function capitalizePhase3(phase) {
26174
26338
  }
26175
26339
 
26176
26340
  // ../core/dist/transition-engine.js
26177
- var defaultLogger12 = createLogger2("TransitionEngine");
26341
+ var defaultLogger13 = createLogger2("TransitionEngine");
26178
26342
  var TransitionEngine2 = class {
26179
26343
  workflowManager;
26180
26344
  logger;
26181
26345
  conversationManager;
26182
- constructor(projectPath, logger37 = defaultLogger12) {
26346
+ constructor(projectPath, logger37 = defaultLogger13) {
26183
26347
  this.workflowManager = new WorkflowManager2();
26184
26348
  this.logger = logger37;
26185
26349
  this.logger.info("TransitionEngine initialized", { projectPath });
@@ -26350,7 +26514,7 @@ ${continueTransition.additional_instructions}`;
26350
26514
 
26351
26515
  // ../core/dist/file-storage.js
26352
26516
  import { promises as fs9 } from "fs";
26353
- import { join as join7, dirname as dirname7 } from "path";
26517
+ import { join as join9, dirname as dirname7 } from "path";
26354
26518
  var logger28 = createLogger2("FileStorage");
26355
26519
  var FileStorage2 = class {
26356
26520
  conversationsDir;
@@ -26360,7 +26524,7 @@ var FileStorage2 = class {
26360
26524
  */
26361
26525
  constructor(basePath) {
26362
26526
  this.basePath = basePath;
26363
- this.conversationsDir = join7(dirname7(basePath), "conversations");
26527
+ this.conversationsDir = join9(dirname7(basePath), "conversations");
26364
26528
  }
26365
26529
  /**
26366
26530
  * Initialize file-based storage
@@ -26381,19 +26545,19 @@ var FileStorage2 = class {
26381
26545
  * Get the directory path for a conversation
26382
26546
  */
26383
26547
  getConversationDir(conversationId) {
26384
- return join7(this.conversationsDir, conversationId);
26548
+ return join9(this.conversationsDir, conversationId);
26385
26549
  }
26386
26550
  /**
26387
26551
  * Get the state file path for a conversation
26388
26552
  */
26389
26553
  getStateFilePath(conversationId) {
26390
- return join7(this.getConversationDir(conversationId), "state.json");
26554
+ return join9(this.getConversationDir(conversationId), "state.json");
26391
26555
  }
26392
26556
  /**
26393
26557
  * Get the interactions file path for a conversation
26394
26558
  */
26395
26559
  getInteractionsFilePath(conversationId) {
26396
- return join7(this.getConversationDir(conversationId), "interactions.jsonl");
26560
+ return join9(this.getConversationDir(conversationId), "interactions.jsonl");
26397
26561
  }
26398
26562
  /**
26399
26563
  * Write data atomically using temp file + rename
@@ -26613,7 +26777,7 @@ import { existsSync as existsSync4 } from "fs";
26613
26777
 
26614
26778
  // ../core/dist/path-validation-utils.js
26615
26779
  import { access as access4, stat as stat4 } from "fs/promises";
26616
- import { resolve as resolve4, isAbsolute as isAbsolute2, join as join9, normalize as normalize2, basename as basename3 } from "path";
26780
+ import { resolve as resolve4, isAbsolute as isAbsolute2, join as join11, normalize as normalize2, basename as basename3 } from "path";
26617
26781
  var logger29 = createLogger2("PathValidationUtils");
26618
26782
  function getPathBasename2(filePath, fallback = "unknown") {
26619
26783
  if (!filePath) {
@@ -26626,7 +26790,7 @@ function getPathBasename2(filePath, fallback = "unknown") {
26626
26790
  }
26627
26791
 
26628
26792
  // ../core/dist/plan-manager.js
26629
- import { writeFile as writeFile5, readFile as readFile5, access as access6 } from "fs/promises";
26793
+ import { writeFile as writeFile6, readFile as readFile6, access as access6 } from "fs/promises";
26630
26794
  import { dirname as dirname8 } from "path";
26631
26795
  import { mkdir as mkdir4 } from "fs/promises";
26632
26796
  var logger30 = createLogger2("PlanManager");
@@ -26657,7 +26821,7 @@ var PlanManager2 = class {
26657
26821
  async getPlanFileInfo(planFilePath) {
26658
26822
  try {
26659
26823
  await access6(planFilePath);
26660
- const content = await readFile5(planFilePath, "utf-8");
26824
+ const content = await readFile6(planFilePath, "utf-8");
26661
26825
  return {
26662
26826
  path: planFilePath,
26663
26827
  exists: true,
@@ -26703,7 +26867,7 @@ var PlanManager2 = class {
26703
26867
  const projectName = getPathBasename2(projectPath, "Unknown Project");
26704
26868
  const branchInfo = gitBranch !== "no-git" ? ` (${gitBranch} branch)` : "";
26705
26869
  const initialContent = this.generateInitialPlanContent(projectName, branchInfo);
26706
- await writeFile5(planFilePath, initialContent, "utf-8");
26870
+ await writeFile6(planFilePath, initialContent, "utf-8");
26707
26871
  logger30.info("Initial plan file written successfully", {
26708
26872
  planFilePath,
26709
26873
  contentLength: initialContent.length,
@@ -26774,7 +26938,7 @@ var PlanManager2 = class {
26774
26938
  */
26775
26939
  async updatePlanFile(planFilePath, content) {
26776
26940
  await mkdir4(dirname8(planFilePath), { recursive: true });
26777
- await writeFile5(planFilePath, content, "utf-8");
26941
+ await writeFile6(planFilePath, content, "utf-8");
26778
26942
  }
26779
26943
  /**
26780
26944
  * Get plan file content for LLM context
@@ -27233,8 +27397,8 @@ var ConversationManager2 = class {
27233
27397
  };
27234
27398
 
27235
27399
  // ../core/dist/template-manager.js
27236
- import { readFile as readFile6, readdir as readdir3, stat as stat5 } from "fs/promises";
27237
- import { join as join10, dirname as dirname9 } from "path";
27400
+ import { readFile as readFile7, readdir as readdir3, stat as stat5 } from "fs/promises";
27401
+ import { join as join12, dirname as dirname9 } from "path";
27238
27402
  import { fileURLToPath as fileURLToPath8 } from "url";
27239
27403
  import { createRequire as createRequire6 } from "module";
27240
27404
  var logger32 = createLogger2("TemplateManager");
@@ -27248,19 +27412,19 @@ var TemplateManager2 = class {
27248
27412
  */
27249
27413
  resolveTemplatesPath() {
27250
27414
  const strategies = [];
27251
- strategies.push(join10(dirname9(fileURLToPath8(import.meta.url)), "../resources/templates"));
27415
+ strategies.push(join12(dirname9(fileURLToPath8(import.meta.url)), "../resources/templates"));
27252
27416
  const currentFileUrl = import.meta.url;
27253
27417
  if (currentFileUrl.startsWith("file://")) {
27254
27418
  const currentFilePath = fileURLToPath8(currentFileUrl);
27255
- strategies.push(join10(dirname9(currentFilePath), "../resources/templates"));
27419
+ strategies.push(join12(dirname9(currentFilePath), "../resources/templates"));
27256
27420
  }
27257
- strategies.push(join10(process.cwd(), "resources/templates"));
27258
- strategies.push(join10(process.cwd(), "node_modules/@codemcp/workflows-core/resources/templates"));
27421
+ strategies.push(join12(process.cwd(), "resources/templates"));
27422
+ strategies.push(join12(process.cwd(), "node_modules/@codemcp/workflows-core/resources/templates"));
27259
27423
  try {
27260
27424
  const require2 = createRequire6(import.meta.url);
27261
27425
  const packagePath = require2.resolve("@codemcp/workflows-core/package.json");
27262
27426
  const packageDir = dirname9(packagePath);
27263
- strategies.push(join10(packageDir, "resources/templates"));
27427
+ strategies.push(join12(packageDir, "resources/templates"));
27264
27428
  } catch (_error) {
27265
27429
  }
27266
27430
  for (const strategy of strategies) {
@@ -27313,7 +27477,7 @@ var TemplateManager2 = class {
27313
27477
  * Load and render a template
27314
27478
  */
27315
27479
  async loadTemplate(type3, template) {
27316
- const templatePath = join10(this.templatesPath, type3, template);
27480
+ const templatePath = join12(this.templatesPath, type3, template);
27317
27481
  const templateFilePath = `${templatePath}.md`;
27318
27482
  try {
27319
27483
  try {
@@ -27323,7 +27487,7 @@ var TemplateManager2 = class {
27323
27487
  }
27324
27488
  } catch (_error) {
27325
27489
  }
27326
- const content = await readFile6(templateFilePath, "utf-8");
27490
+ const content = await readFile7(templateFilePath, "utf-8");
27327
27491
  return { content };
27328
27492
  } catch (error) {
27329
27493
  logger32.error(`Failed to load template: ${type3}/${template}`, error);
@@ -27340,7 +27504,7 @@ var TemplateManager2 = class {
27340
27504
  if (!markdownFile) {
27341
27505
  throw new Error(`No markdown file found in template directory: ${templatePath}`);
27342
27506
  }
27343
- const content = await readFile6(join10(templatePath, markdownFile), "utf-8");
27507
+ const content = await readFile7(join12(templatePath, markdownFile), "utf-8");
27344
27508
  await this.loadAdditionalFiles(templatePath, "", additionalFiles);
27345
27509
  return {
27346
27510
  content,
@@ -27351,16 +27515,16 @@ var TemplateManager2 = class {
27351
27515
  * Recursively load additional files from template directory
27352
27516
  */
27353
27517
  async loadAdditionalFiles(basePath, relativePath, additionalFiles) {
27354
- const currentPath = join10(basePath, relativePath);
27518
+ const currentPath = join12(basePath, relativePath);
27355
27519
  const items = await readdir3(currentPath);
27356
27520
  for (const item of items) {
27357
- const itemPath = join10(currentPath, item);
27358
- const itemRelativePath = relativePath ? join10(relativePath, item) : item;
27521
+ const itemPath = join12(currentPath, item);
27522
+ const itemRelativePath = relativePath ? join12(relativePath, item) : item;
27359
27523
  const stats = await stat5(itemPath);
27360
27524
  if (stats.isDirectory()) {
27361
27525
  await this.loadAdditionalFiles(basePath, itemRelativePath, additionalFiles);
27362
27526
  } else if (!item.endsWith(".md")) {
27363
- const content = await readFile6(itemPath);
27527
+ const content = await readFile7(itemPath);
27364
27528
  additionalFiles.push({
27365
27529
  relativePath: itemRelativePath,
27366
27530
  content
@@ -27394,7 +27558,7 @@ var TemplateManager2 = class {
27394
27558
  };
27395
27559
  try {
27396
27560
  for (const [type3, templates] of Object.entries(result)) {
27397
- const typePath = join10(this.templatesPath, type3);
27561
+ const typePath = join12(this.templatesPath, type3);
27398
27562
  try {
27399
27563
  const entries = await readdir3(typePath, { withFileTypes: true });
27400
27564
  for (const entry of entries) {
@@ -27423,14 +27587,14 @@ var TemplateManager2 = class {
27423
27587
  };
27424
27588
 
27425
27589
  // ../core/dist/project-docs-manager.js
27426
- import { writeFile as writeFile6, access as access7, mkdir as mkdir5, unlink as unlink2, symlink as symlink2, lstat as lstat2, stat as stat6, readdir as readdir4 } from "fs/promises";
27427
- import { join as join11, dirname as dirname10, relative as relative2, extname as extname2, basename as basename5 } from "path";
27428
- var defaultLogger13 = createLogger2("ProjectDocsManager");
27590
+ import { writeFile as writeFile7, access as access7, mkdir as mkdir5, unlink as unlink2, symlink as symlink2, lstat as lstat2, stat as stat6, readdir as readdir4 } from "fs/promises";
27591
+ import { join as join13, dirname as dirname10, relative as relative2, extname as extname2, basename as basename5 } from "path";
27592
+ var defaultLogger14 = createLogger2("ProjectDocsManager");
27429
27593
  var ProjectDocsManager2 = class {
27430
27594
  templateManager;
27431
27595
  // Make public for access from other classes
27432
27596
  logger;
27433
- constructor(logger37 = defaultLogger13) {
27597
+ constructor(logger37 = defaultLogger14) {
27434
27598
  this.templateManager = new TemplateManager2();
27435
27599
  this.logger = logger37;
27436
27600
  }
@@ -27438,7 +27602,7 @@ var ProjectDocsManager2 = class {
27438
27602
  * Get project docs directory path
27439
27603
  */
27440
27604
  getDocsPath(projectPath) {
27441
- return join11(projectPath, ".vibe", "docs");
27605
+ return join13(projectPath, ".vibe", "docs");
27442
27606
  }
27443
27607
  /**
27444
27608
  * Determine the appropriate extension for a document based on source path
@@ -27471,9 +27635,9 @@ var ProjectDocsManager2 = class {
27471
27635
  getDocumentPaths(projectPath) {
27472
27636
  const docsPath = this.getDocsPath(projectPath);
27473
27637
  return {
27474
- architecture: join11(docsPath, "architecture.md"),
27475
- requirements: join11(docsPath, "requirements.md"),
27476
- design: join11(docsPath, "design.md")
27638
+ architecture: join13(docsPath, "architecture.md"),
27639
+ requirements: join13(docsPath, "requirements.md"),
27640
+ design: join13(docsPath, "design.md")
27477
27641
  };
27478
27642
  }
27479
27643
  /**
@@ -27485,9 +27649,9 @@ var ProjectDocsManager2 = class {
27485
27649
  const reqFilename = await this.getDocumentFilename("requirements", sourcePaths?.requirements);
27486
27650
  const designFilename = await this.getDocumentFilename("design", sourcePaths?.design);
27487
27651
  return {
27488
- architecture: join11(docsPath, archFilename),
27489
- requirements: join11(docsPath, reqFilename),
27490
- design: join11(docsPath, designFilename)
27652
+ architecture: join13(docsPath, archFilename),
27653
+ requirements: join13(docsPath, reqFilename),
27654
+ design: join13(docsPath, designFilename)
27491
27655
  };
27492
27656
  }
27493
27657
  /**
@@ -27513,7 +27677,7 @@ var ProjectDocsManager2 = class {
27513
27677
  for (const entry of entries) {
27514
27678
  const entryWithoutExt = entry.replace(/\.[^/.]+$/, "");
27515
27679
  if (entryWithoutExt === docType || entry === docType) {
27516
- const entryPath = join11(docsDir, entry);
27680
+ const entryPath = join13(docsDir, entry);
27517
27681
  if (await checkExists(entryPath)) {
27518
27682
  return { exists: true, actualPath: entryPath };
27519
27683
  }
@@ -27662,13 +27826,13 @@ var ProjectDocsManager2 = class {
27662
27826
  async createDocument(type3, template, documentPath, docsPath) {
27663
27827
  try {
27664
27828
  const templateResult = await this.templateManager.loadTemplate(type3, template);
27665
- await writeFile6(documentPath, templateResult.content, "utf-8");
27829
+ await writeFile7(documentPath, templateResult.content, "utf-8");
27666
27830
  if (templateResult.additionalFiles) {
27667
27831
  for (const file of templateResult.additionalFiles) {
27668
- const filePath = join11(docsPath, file.relativePath);
27832
+ const filePath = join13(docsPath, file.relativePath);
27669
27833
  const fileDir = dirname10(filePath);
27670
27834
  await mkdir5(fileDir, { recursive: true });
27671
- await writeFile6(filePath, file.content.toString());
27835
+ await writeFile7(filePath, file.content.toString());
27672
27836
  }
27673
27837
  }
27674
27838
  this.logger.debug(`Created ${type3} document`, { documentPath, template });
@@ -27686,7 +27850,7 @@ var ProjectDocsManager2 = class {
27686
27850
  getVariableSubstitutions(projectPath, gitBranch) {
27687
27851
  const paths = this.getDocumentPaths(projectPath);
27688
27852
  const branchDirName = gitBranch || "main";
27689
- const vibeDir = join11(projectPath, ".vibe");
27853
+ const vibeDir = join13(projectPath, ".vibe");
27690
27854
  const agentRole = process.env["VIBE_ROLE"] || "";
27691
27855
  return {
27692
27856
  $ARCHITECTURE_DOC: paths.architecture,
@@ -27743,7 +27907,7 @@ var ProjectDocsManager2 = class {
27743
27907
 
27744
27908
  // ../core/dist/file-detection-manager.js
27745
27909
  import { readdir as readdir5, access as access8 } from "fs/promises";
27746
- import { join as join12, basename as basename6 } from "path";
27910
+ import { join as join14, basename as basename6 } from "path";
27747
27911
  var logger33 = createLogger2("FileDetectionManager");
27748
27912
 
27749
27913
  // ../core/dist/git-manager.js
@@ -27753,16 +27917,16 @@ var logger34 = createLogger2("GitManager");
27753
27917
 
27754
27918
  // ../core/dist/task-backend.js
27755
27919
  import { execSync as execSync9 } from "child_process";
27756
- var defaultLogger14 = createLogger2("TaskBackend");
27920
+ var defaultLogger15 = createLogger2("TaskBackend");
27757
27921
 
27758
27922
  // ../core/dist/beads-integration.js
27759
27923
  import { execSync as execSync10 } from "child_process";
27760
- var defaultLogger15 = createLogger2("BeadsIntegration");
27924
+ var defaultLogger16 = createLogger2("BeadsIntegration");
27761
27925
 
27762
27926
  // ../core/dist/beads-state-manager.js
27763
- import { writeFile as writeFile7, readFile as readFile7, mkdir as mkdir6, access as access9 } from "fs/promises";
27764
- import { join as join13, dirname as dirname11 } from "path";
27765
- var defaultLogger16 = createLogger2("BeadsStateManager");
27927
+ import { writeFile as writeFile8, readFile as readFile8, mkdir as mkdir6, access as access9 } from "fs/promises";
27928
+ import { join as join15, dirname as dirname11 } from "path";
27929
+ var defaultLogger17 = createLogger2("BeadsStateManager");
27766
27930
 
27767
27931
  // ../core/dist/interaction-logger.js
27768
27932
  var logger35 = createLogger2("InteractionLogger");
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemcp/workflows-opencode",
3
- "version": "6.7.0",
3
+ "version": "6.9.0",
4
4
  "description": "OpenCode plugin for structured development workflows",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemcp/workflows-opencode-tui",
3
- "version": "6.7.0",
3
+ "version": "6.9.0",
4
4
  "description": "OpenCode TUI sidebar plugin that displays the current responsible-vibe workflow phase and name",
5
5
  "main": "workflows-phase.tsx",
6
6
  "exports": {
@@ -20,11 +20,13 @@
20
20
  "format": "prettier --write ."
21
21
  },
22
22
  "peerDependencies": {
23
+ "@codemcp/workflows-core": "*",
23
24
  "@opencode-ai/plugin": "*",
24
25
  "@opentui/solid": "*",
25
26
  "solid-js": "*"
26
27
  },
27
28
  "devDependencies": {
29
+ "@codemcp/workflows-core": "workspace:*",
28
30
  "@opencode-ai/plugin": "*",
29
31
  "@opentui/solid": "*",
30
32
  "@types/node": "^22.0.0",