wogiflow 2.4.0 → 2.4.2

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.
@@ -4,9 +4,9 @@ effort: medium
4
4
  ---
5
5
  Save workflow state (task progress, checkpoints, session context) before context compaction.
6
6
 
7
- **Why "pre-compact"**: This skill saves state but cannot trigger `/compact` programmatically `/compact` is a Claude Code native command that only the user or Claude Code's auto-compaction can invoke. Once Claude Code exposes compaction as a programmable tool, this will be renamed back to `/wogi-compact` and will handle the full save-then-compact flow automatically.
7
+ **CRITICAL NEVER ASK THE USER TO COMPACT**: After saving state, output the session summary and then run `/compact` yourself immediately. Do NOT say "Now run /compact" or ask the user to do anything. Compaction must be seamless and invisible to the user. The PostCompact hook restores critical state automatically.
8
8
 
9
- **After running this**: Run `/compact` to actually compact the context. The PostCompact hook will restore critical state automatically.
9
+ **NEVER INVOKE THIS PROACTIVELY**: This skill should only run when the user explicitly asks to compact or save context. If you think context is getting large mid-task, let Claude Code's auto-compaction handle it — do NOT invoke this skill yourself. The user said "implement" not "compact".
10
10
 
11
11
  ## Recursive Context Compaction
12
12
 
@@ -206,4 +206,6 @@ node node_modules/wogiflow/scripts/flow-context-compact compact --prune
206
206
  node node_modules/wogiflow/scripts/flow-context-compact context "authentication task"
207
207
  ```
208
208
 
209
- After providing the summary, proceed directly: run `/compact` immediately. Do NOT ask the user for permission auto-compaction must be seamless and uninterrupted. If invoked mid-bulk or between tasks, compact silently and continue to the next task.
209
+ After providing the summary, run `/compact` immediately no confirmation, no "Now run /compact", no waiting. The user must NEVER be asked to compact manually. If invoked mid-bulk or between tasks, compact silently and continue to the next task.
210
+
211
+ **Anti-pattern (BANNED)**: Outputting "Now run /compact to compact the context" or any variant that asks the user to take action. This has frustrated the user multiple times. YOU run /compact, not the user.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wogiflow",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "AI-powered development workflow management system with multi-model support",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -15,8 +15,10 @@
15
15
  * v1.0: Initial implementation — pre-commit blocking gate
16
16
  */
17
17
 
18
+ const fs = require('node:fs');
19
+ const path = require('node:path');
18
20
  const { execFileSync } = require('node:child_process');
19
- const { getConfig, getReadyData } = require('../../flow-utils');
21
+ const { getConfig, getReadyData, PATHS } = require('../../flow-utils');
20
22
 
21
23
  /**
22
24
  * Check if a Bash command contains a git commit
@@ -120,25 +122,34 @@ function checkCommitLogGate(command, config) {
120
122
  return { allowed: true, blocked: false };
121
123
  }
122
124
 
123
- // Check if request-log.md is in staged changes
124
- const hasLogEntry = stagedFiles.some(f => f.endsWith('request-log.md'));
125
+ // Check if request-log.md contains an entry for the active task.
126
+ // We check file content instead of git staging because .workflow/ may be
127
+ // in .gitignore (intentional user choice to keep state files out of git).
128
+ // Checking staged files would silently fail when the directory is gitignored.
129
+ const task = readyData.inProgress[0];
130
+ const taskId = (typeof task === 'string' ? task : task.id) || 'unknown';
131
+
132
+ const logPath = path.join(PATHS.state, 'request-log.md');
133
+ let hasLogEntry = false;
134
+ try {
135
+ const logContent = fs.readFileSync(logPath, 'utf-8');
136
+ hasLogEntry = logContent.includes(taskId);
137
+ } catch (_err) {
138
+ // File doesn't exist or can't be read — no log entry
139
+ }
140
+
125
141
  if (hasLogEntry) {
126
142
  return { allowed: true, blocked: false };
127
143
  }
128
144
 
129
- // Block: active task + code changes but no log entry
130
- const task = readyData.inProgress[0];
131
- const taskId = (typeof task === 'string' ? task : task.id) || 'unknown';
132
-
133
145
  return {
134
146
  allowed: false,
135
147
  blocked: true,
136
148
  reason: 'commit_without_log_entry',
137
149
  message: [
138
- `BLOCKED: Active task ${taskId} but request-log.md is not staged.`,
150
+ `BLOCKED: Active task ${taskId} but no request-log entry found.`,
139
151
  'Add a request-log entry before committing.',
140
- 'Append a ### R-[N] entry to .workflow/state/request-log.md following the existing format,',
141
- 'then stage it: git add .workflow/state/request-log.md'
152
+ `Append a ### R-[N] entry referencing ${taskId} to .workflow/state/request-log.md following the existing format.`
142
153
  ].join(' ')
143
154
  };
144
155
  }
@@ -296,6 +296,33 @@ function checkTaskGate(options = {}, config) {
296
296
  };
297
297
  }
298
298
 
299
+ // getActiveTask() returned null — check if a task EXISTS in inProgress
300
+ // but was rejected for missing routing proof (routedAt + receipt).
301
+ // This gives the AI an actionable error instead of the misleading "no active task".
302
+ try {
303
+ const readyData = getReadyData();
304
+ if (readyData.inProgress && readyData.inProgress.length > 0) {
305
+ const task = readyData.inProgress[0];
306
+ const taskId = typeof task === 'string' ? task : task.id;
307
+ if (taskId) {
308
+ trackBypassAttempt({
309
+ filePath,
310
+ operation,
311
+ reason: 'task_missing_routing_proof',
312
+ taskId
313
+ });
314
+ return {
315
+ allowed: false,
316
+ blocked: true,
317
+ message: `Task ${taskId} is in inProgress but has no routing proof (missing routedAt and no routing receipt file).\n\nThis usually means the task was inserted into ready.json manually instead of through /wogi-start.\n\nTo fix:\n1. Use /wogi-start ${taskId} to properly route this task\n2. Or remove it from inProgress and start fresh: /wogi-ready`,
318
+ reason: 'task_missing_routing_proof'
319
+ };
320
+ }
321
+ }
322
+ } catch (_err) {
323
+ // Fall through to normal "no active task" path
324
+ }
325
+
299
326
  // No active task - should we block?
300
327
  const shouldBlock = config.enforcement?.taskGating?.blockWithoutTask !== false;
301
328