wogiflow 2.18.0 → 2.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wogiflow",
3
- "version": "2.18.0",
3
+ "version": "2.18.1",
4
4
  "description": "AI-powered development workflow management system with multi-model support",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -418,19 +418,104 @@ function generateWarningMessage(operation, filePath) {
418
418
  return `Warning: ${operation === 'write' ? 'Creating' : 'Editing'} ${fileName} without an active task. Consider starting a task first.`;
419
419
  }
420
420
 
421
+ // Rule / memory files where /wogi-decide is the idiomatic capture command.
422
+ // Intent artifacts (domain-model.md, user-journeys.md, glossary.md, product.md)
423
+ // are deliberately excluded — modifying those is product-design work and should
424
+ // flow through /wogi-story per the normal task lifecycle.
425
+ const RULE_FILE_BASENAMES = new Set([
426
+ 'decisions.md',
427
+ 'feedback-patterns.md',
428
+ 'MEMORY.md'
429
+ ]);
430
+
431
+ /**
432
+ * Detect whether the given file path (or its basename) is a rule/memory file
433
+ * that should route to /wogi-decide for capture instead of /wogi-story.
434
+ *
435
+ * Also matches Claude Code auto-memory paths under `.claude/projects/*\/memory/`.
436
+ */
437
+ function isRuleOrMemoryFile(filePath) {
438
+ if (!filePath || typeof filePath !== 'string') return false;
439
+ const base = path.basename(filePath);
440
+ if (RULE_FILE_BASENAMES.has(base)) return true;
441
+ if (filePath.includes(`${path.sep}.claude${path.sep}projects${path.sep}`) &&
442
+ filePath.includes(`${path.sep}memory${path.sep}`)) return true;
443
+ return false;
444
+ }
445
+
446
+ /**
447
+ * Detect whether the current working directory (or its parents) contains a
448
+ * `.workspace/` directory — the marker for WogiFlow workspace mode where a
449
+ * manager repo coordinates worker repos. When present, the block message
450
+ * additionally suggests the workspace-coordination task pattern.
451
+ *
452
+ * Walks up at most 6 parents to avoid unbounded traversal.
453
+ */
454
+ function isInWorkspaceMode(startDir) {
455
+ const start = startDir || process.cwd();
456
+ try {
457
+ let dir = start;
458
+ for (let i = 0; i < 6; i++) {
459
+ const candidate = path.join(dir, '.workspace');
460
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
461
+ return true;
462
+ }
463
+ const parent = path.dirname(dir);
464
+ if (parent === dir) break;
465
+ dir = parent;
466
+ }
467
+ } catch (_err) {
468
+ // Filesystem errors (permissions, etc.) → conservatively say no. The
469
+ // standard suggestions are still shown, so the user is never stranded.
470
+ }
471
+ return false;
472
+ }
473
+
421
474
  /**
422
- * Generate block message
475
+ * Generate block message (context-aware).
476
+ *
477
+ * The message adapts to two signals:
478
+ * 1. If the blocked path is a rule/memory file (e.g. decisions.md), the
479
+ * message leads with `/wogi-decide` — the idiomatic "from now on" rule
480
+ * capture command that doesn't require a code task.
481
+ * 2. If a `.workspace/` directory exists at cwd or a parent, the message
482
+ * adds a workspace-coordination task pattern.
483
+ *
484
+ * Enforcement behavior is unchanged — this only affects the text shown to
485
+ * the AI / user when the gate blocks. Intent artifacts (domain-model.md,
486
+ * user-journeys.md, glossary.md, product.md) deliberately do NOT trigger
487
+ * the rule-file branch — those still route to /wogi-story.
423
488
  */
424
489
  function generateBlockMessage(operation, filePath) {
425
490
  const fileName = filePath ? path.basename(filePath) : 'file';
426
- return `Cannot ${operation} ${fileName} without an active task.
491
+ const isRuleFile = isRuleOrMemoryFile(filePath);
492
+ const inWorkspace = isInWorkspaceMode();
493
+
494
+ const lines = [`Cannot ${operation} ${fileName} without an active task.`, ''];
427
495
 
428
- To proceed:
429
- 1. Check available tasks: /wogi-ready
430
- 2. Start an existing task: /wogi-start wf-XXXXXXXX
431
- 3. Or create a new task: /wogi-story "description"
496
+ if (isRuleFile) {
497
+ lines.push('For rule / memory capture without a code task:');
498
+ lines.push(' /wogi-decide "from now on, <your rule>"');
499
+ lines.push('');
500
+ }
501
+
502
+ if (inWorkspace) {
503
+ lines.push('For workspace coordination (manager repo in workspace mode):');
504
+ lines.push(' /wogi-start "coordinate wf-XXXXXXXX in workspace"');
505
+ lines.push('');
506
+ }
432
507
 
433
- Task gating is enforced when strictMode is enabled.`;
508
+ lines.push('For a side thought or idea to save for later:');
509
+ lines.push(' /wogi-capture "your idea"');
510
+ lines.push('');
511
+ lines.push('Other options:');
512
+ lines.push(' /wogi-ready → see available tasks');
513
+ lines.push(' /wogi-start wf-XXXXXXXX → start an existing task');
514
+ lines.push(' /wogi-story "description" → create a new task');
515
+ lines.push('');
516
+ lines.push('Task gating is enforced when strictMode is enabled.');
517
+
518
+ return lines.join('\n');
434
519
  }
435
520
 
436
521
  module.exports = {