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
|
@@ -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
|
-
|
|
491
|
+
const isRuleFile = isRuleOrMemoryFile(filePath);
|
|
492
|
+
const inWorkspace = isInWorkspaceMode();
|
|
493
|
+
|
|
494
|
+
const lines = [`Cannot ${operation} ${fileName} without an active task.`, ''];
|
|
427
495
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
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
|
-
|
|
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 = {
|