wogiflow 1.0.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 (221) hide show
  1. package/.workflow/agents/reviewer.md +81 -0
  2. package/.workflow/agents/security.md +94 -0
  3. package/.workflow/agents/story-writer.md +58 -0
  4. package/.workflow/bridges/base-bridge.js +395 -0
  5. package/.workflow/bridges/claude-bridge.js +434 -0
  6. package/.workflow/bridges/index.js +130 -0
  7. package/.workflow/lib/assumption-detector.js +481 -0
  8. package/.workflow/lib/config-substitution.js +371 -0
  9. package/.workflow/lib/failure-categories.js +478 -0
  10. package/.workflow/state/app-map.md.template +15 -0
  11. package/.workflow/state/architecture.md.template +24 -0
  12. package/.workflow/state/component-index.json.template +5 -0
  13. package/.workflow/state/decisions.md.template +15 -0
  14. package/.workflow/state/feedback-patterns.md.template +9 -0
  15. package/.workflow/state/knowledge-sync.json.template +6 -0
  16. package/.workflow/state/progress.md.template +14 -0
  17. package/.workflow/state/ready.json.template +7 -0
  18. package/.workflow/state/request-log.md.template +14 -0
  19. package/.workflow/state/session-state.json.template +11 -0
  20. package/.workflow/state/stack.md.template +33 -0
  21. package/.workflow/state/testing.md.template +36 -0
  22. package/.workflow/templates/claude-md.hbs +257 -0
  23. package/.workflow/templates/correction-report.md +67 -0
  24. package/.workflow/templates/gemini-md.hbs +52 -0
  25. package/README.md +1802 -0
  26. package/bin/flow +205 -0
  27. package/lib/index.js +33 -0
  28. package/lib/installer.js +467 -0
  29. package/lib/release-channel.js +269 -0
  30. package/lib/skill-registry.js +526 -0
  31. package/lib/upgrader.js +401 -0
  32. package/lib/utils.js +305 -0
  33. package/package.json +64 -0
  34. package/scripts/flow +985 -0
  35. package/scripts/flow-adaptive-learning.js +1259 -0
  36. package/scripts/flow-aggregate.js +488 -0
  37. package/scripts/flow-archive +133 -0
  38. package/scripts/flow-auto-context.js +1015 -0
  39. package/scripts/flow-auto-learn.js +615 -0
  40. package/scripts/flow-bridge.js +223 -0
  41. package/scripts/flow-browser-suggest.js +316 -0
  42. package/scripts/flow-bug.js +247 -0
  43. package/scripts/flow-cascade.js +711 -0
  44. package/scripts/flow-changelog +85 -0
  45. package/scripts/flow-checkpoint.js +483 -0
  46. package/scripts/flow-cli.js +403 -0
  47. package/scripts/flow-code-intelligence.js +760 -0
  48. package/scripts/flow-complexity.js +502 -0
  49. package/scripts/flow-config-set.js +152 -0
  50. package/scripts/flow-constants.js +157 -0
  51. package/scripts/flow-context +152 -0
  52. package/scripts/flow-context-init.js +482 -0
  53. package/scripts/flow-context-monitor.js +384 -0
  54. package/scripts/flow-context-scoring.js +886 -0
  55. package/scripts/flow-correct.js +458 -0
  56. package/scripts/flow-damage-control.js +985 -0
  57. package/scripts/flow-deps +101 -0
  58. package/scripts/flow-diff.js +700 -0
  59. package/scripts/flow-done +151 -0
  60. package/scripts/flow-done.js +489 -0
  61. package/scripts/flow-durable-session.js +1541 -0
  62. package/scripts/flow-entropy-monitor.js +345 -0
  63. package/scripts/flow-export-profile +349 -0
  64. package/scripts/flow-export-scanner.js +1046 -0
  65. package/scripts/flow-figma-confirm.js +400 -0
  66. package/scripts/flow-figma-extract.js +496 -0
  67. package/scripts/flow-figma-generate.js +683 -0
  68. package/scripts/flow-figma-index.js +909 -0
  69. package/scripts/flow-figma-match.js +617 -0
  70. package/scripts/flow-figma-mcp-server.js +518 -0
  71. package/scripts/flow-figma-pipeline.js +414 -0
  72. package/scripts/flow-file-ops.js +301 -0
  73. package/scripts/flow-gate-confidence.js +825 -0
  74. package/scripts/flow-guided-edit.js +659 -0
  75. package/scripts/flow-health +185 -0
  76. package/scripts/flow-health.js +413 -0
  77. package/scripts/flow-hooks.js +556 -0
  78. package/scripts/flow-http-client.js +249 -0
  79. package/scripts/flow-hybrid-detect.js +167 -0
  80. package/scripts/flow-hybrid-interactive.js +591 -0
  81. package/scripts/flow-hybrid-test.js +152 -0
  82. package/scripts/flow-import-profile +439 -0
  83. package/scripts/flow-init +253 -0
  84. package/scripts/flow-instruction-richness.js +827 -0
  85. package/scripts/flow-jira-integration.js +579 -0
  86. package/scripts/flow-knowledge-router.js +522 -0
  87. package/scripts/flow-knowledge-sync.js +589 -0
  88. package/scripts/flow-linear-integration.js +631 -0
  89. package/scripts/flow-links.js +774 -0
  90. package/scripts/flow-log-manager.js +559 -0
  91. package/scripts/flow-loop-enforcer.js +1246 -0
  92. package/scripts/flow-loop-retry-learning.js +630 -0
  93. package/scripts/flow-lsp.js +923 -0
  94. package/scripts/flow-map-index +348 -0
  95. package/scripts/flow-map-sync +201 -0
  96. package/scripts/flow-memory-blocks.js +668 -0
  97. package/scripts/flow-memory-compactor.js +350 -0
  98. package/scripts/flow-memory-db.js +1110 -0
  99. package/scripts/flow-memory-sync.js +484 -0
  100. package/scripts/flow-metrics.js +353 -0
  101. package/scripts/flow-migrate-ids.js +370 -0
  102. package/scripts/flow-model-adapter.js +802 -0
  103. package/scripts/flow-model-router.js +884 -0
  104. package/scripts/flow-models.js +1231 -0
  105. package/scripts/flow-morning.js +517 -0
  106. package/scripts/flow-multi-approach.js +660 -0
  107. package/scripts/flow-new-feature +86 -0
  108. package/scripts/flow-onboard +1042 -0
  109. package/scripts/flow-orchestrate-llm.js +459 -0
  110. package/scripts/flow-orchestrate.js +3592 -0
  111. package/scripts/flow-output.js +123 -0
  112. package/scripts/flow-parallel-detector.js +399 -0
  113. package/scripts/flow-parallel-dispatch.js +987 -0
  114. package/scripts/flow-parallel.js +428 -0
  115. package/scripts/flow-pattern-enforcer.js +600 -0
  116. package/scripts/flow-prd-manager.js +282 -0
  117. package/scripts/flow-progress.js +323 -0
  118. package/scripts/flow-project-analyzer.js +975 -0
  119. package/scripts/flow-prompt-composer.js +487 -0
  120. package/scripts/flow-providers.js +1381 -0
  121. package/scripts/flow-queue.js +308 -0
  122. package/scripts/flow-ready +82 -0
  123. package/scripts/flow-ready.js +189 -0
  124. package/scripts/flow-regression.js +396 -0
  125. package/scripts/flow-response-parser.js +450 -0
  126. package/scripts/flow-resume.js +284 -0
  127. package/scripts/flow-rules-sync.js +439 -0
  128. package/scripts/flow-run-trace.js +718 -0
  129. package/scripts/flow-safety.js +587 -0
  130. package/scripts/flow-search +104 -0
  131. package/scripts/flow-security.js +481 -0
  132. package/scripts/flow-session-end +106 -0
  133. package/scripts/flow-session-end.js +437 -0
  134. package/scripts/flow-session-state.js +671 -0
  135. package/scripts/flow-setup-hooks +216 -0
  136. package/scripts/flow-setup-hooks.js +377 -0
  137. package/scripts/flow-skill-create.js +329 -0
  138. package/scripts/flow-skill-creator.js +572 -0
  139. package/scripts/flow-skill-generator.js +1046 -0
  140. package/scripts/flow-skill-learn.js +880 -0
  141. package/scripts/flow-skill-matcher.js +578 -0
  142. package/scripts/flow-spec-generator.js +820 -0
  143. package/scripts/flow-stack-wizard.js +895 -0
  144. package/scripts/flow-standup +162 -0
  145. package/scripts/flow-start +74 -0
  146. package/scripts/flow-start.js +235 -0
  147. package/scripts/flow-status +110 -0
  148. package/scripts/flow-status.js +301 -0
  149. package/scripts/flow-step-browser.js +83 -0
  150. package/scripts/flow-step-changelog.js +217 -0
  151. package/scripts/flow-step-comments.js +306 -0
  152. package/scripts/flow-step-complexity.js +234 -0
  153. package/scripts/flow-step-coverage.js +218 -0
  154. package/scripts/flow-step-knowledge.js +193 -0
  155. package/scripts/flow-step-pr-tests.js +364 -0
  156. package/scripts/flow-step-regression.js +89 -0
  157. package/scripts/flow-step-review.js +516 -0
  158. package/scripts/flow-step-security.js +162 -0
  159. package/scripts/flow-step-silent-failures.js +290 -0
  160. package/scripts/flow-step-simplifier.js +346 -0
  161. package/scripts/flow-story +105 -0
  162. package/scripts/flow-story.js +500 -0
  163. package/scripts/flow-suspend.js +252 -0
  164. package/scripts/flow-sync-daemon.js +654 -0
  165. package/scripts/flow-task-analyzer.js +606 -0
  166. package/scripts/flow-team-dashboard.js +748 -0
  167. package/scripts/flow-team-sync.js +752 -0
  168. package/scripts/flow-team.js +977 -0
  169. package/scripts/flow-tech-options.js +528 -0
  170. package/scripts/flow-templates.js +812 -0
  171. package/scripts/flow-tiered-learning.js +728 -0
  172. package/scripts/flow-trace +204 -0
  173. package/scripts/flow-transcript-chunking.js +1106 -0
  174. package/scripts/flow-transcript-digest.js +7918 -0
  175. package/scripts/flow-transcript-language.js +465 -0
  176. package/scripts/flow-transcript-parsing.js +1085 -0
  177. package/scripts/flow-transcript-stories.js +2194 -0
  178. package/scripts/flow-update-map +224 -0
  179. package/scripts/flow-utils.js +2242 -0
  180. package/scripts/flow-verification.js +644 -0
  181. package/scripts/flow-verify.js +1177 -0
  182. package/scripts/flow-voice-input.js +638 -0
  183. package/scripts/flow-watch +168 -0
  184. package/scripts/flow-workflow-steps.js +521 -0
  185. package/scripts/flow-workflow.js +1029 -0
  186. package/scripts/flow-worktree.js +489 -0
  187. package/scripts/hooks/adapters/base-adapter.js +102 -0
  188. package/scripts/hooks/adapters/claude-code.js +359 -0
  189. package/scripts/hooks/adapters/index.js +79 -0
  190. package/scripts/hooks/core/component-check.js +341 -0
  191. package/scripts/hooks/core/index.js +35 -0
  192. package/scripts/hooks/core/loop-check.js +241 -0
  193. package/scripts/hooks/core/session-context.js +294 -0
  194. package/scripts/hooks/core/task-gate.js +177 -0
  195. package/scripts/hooks/core/validation.js +230 -0
  196. package/scripts/hooks/entry/claude-code/post-tool-use.js +65 -0
  197. package/scripts/hooks/entry/claude-code/pre-tool-use.js +89 -0
  198. package/scripts/hooks/entry/claude-code/session-end.js +87 -0
  199. package/scripts/hooks/entry/claude-code/session-start.js +46 -0
  200. package/scripts/hooks/entry/claude-code/stop.js +43 -0
  201. package/scripts/postinstall.js +139 -0
  202. package/templates/browser-test-flow.json +56 -0
  203. package/templates/bug-report.md +43 -0
  204. package/templates/component-detail.md +42 -0
  205. package/templates/component.stories.tsx +49 -0
  206. package/templates/context/constraints.md +83 -0
  207. package/templates/context/conventions.md +177 -0
  208. package/templates/context/stack.md +60 -0
  209. package/templates/correction-report.md +90 -0
  210. package/templates/feature-proposal.md +35 -0
  211. package/templates/hybrid/_base.md +254 -0
  212. package/templates/hybrid/_patterns.md +45 -0
  213. package/templates/hybrid/create-component.md +127 -0
  214. package/templates/hybrid/create-file.md +56 -0
  215. package/templates/hybrid/create-hook.md +145 -0
  216. package/templates/hybrid/create-service.md +70 -0
  217. package/templates/hybrid/fix-bug.md +33 -0
  218. package/templates/hybrid/modify-file.md +55 -0
  219. package/templates/story.md +68 -0
  220. package/templates/task.json +56 -0
  221. package/templates/trace.md +69 -0
@@ -0,0 +1,162 @@
1
+ #!/bin/bash
2
+
3
+ # Wogi Flow - Standup Summary Generator
4
+ # Generates daily standup from request-log and task status
5
+
6
+ set -e
7
+
8
+ WORKFLOW_DIR=".workflow"
9
+ REQUEST_LOG="$WORKFLOW_DIR/state/request-log.md"
10
+ READY_JSON="$WORKFLOW_DIR/state/ready.json"
11
+ PROGRESS_MD="$WORKFLOW_DIR/state/progress.md"
12
+
13
+ # Colors
14
+ CYAN='\033[0;36m'
15
+ GREEN='\033[0;32m'
16
+ YELLOW='\033[1;33m'
17
+ NC='\033[0m'
18
+
19
+ # Get date range (default: last 24 hours)
20
+ DAYS=${1:-1}
21
+ SINCE=$(date -d "$DAYS days ago" +%Y-%m-%d 2>/dev/null || date -v-${DAYS}d +%Y-%m-%d)
22
+
23
+ echo -e "${CYAN}═══════════════════════════════════════${NC}"
24
+ echo -e "${CYAN} STANDUP SUMMARY${NC}"
25
+ echo -e "${CYAN}═══════════════════════════════════════${NC}"
26
+ echo ""
27
+ echo "Period: Last $DAYS day(s) (since $SINCE)"
28
+ echo ""
29
+
30
+ # What was done (from request-log)
31
+ echo -e "${GREEN}✅ COMPLETED${NC}"
32
+ echo "─────────────────────────────────────"
33
+
34
+ if [ -f "$REQUEST_LOG" ]; then
35
+ # Extract entries from the time period
36
+ recent_entries=$(grep -A5 "^### R-" "$REQUEST_LOG" | grep -A5 "$SINCE" 2>/dev/null || true)
37
+
38
+ if [ -n "$recent_entries" ]; then
39
+ # Parse and display
40
+ grep "^### R-" "$REQUEST_LOG" | while read -r line; do
41
+ date_in_entry=$(echo "$line" | grep -oE "[0-9]{4}-[0-9]{2}-[0-9]{2}" || true)
42
+ if [[ "$date_in_entry" > "$SINCE" ]] || [[ "$date_in_entry" == "$SINCE" ]]; then
43
+ entry_id=$(echo "$line" | grep -oE "R-[0-9]+")
44
+ echo " • $entry_id"
45
+ fi
46
+ done
47
+
48
+ # Count by type
49
+ echo ""
50
+ new_count=$(grep -c "Type.*: new" "$REQUEST_LOG" 2>/dev/null || echo 0)
51
+ fix_count=$(grep -c "Type.*: fix" "$REQUEST_LOG" 2>/dev/null || echo 0)
52
+ change_count=$(grep -c "Type.*: change" "$REQUEST_LOG" 2>/dev/null || echo 0)
53
+
54
+ echo " Summary: $new_count new, $fix_count fixes, $change_count changes"
55
+ else
56
+ echo " No logged work in this period"
57
+ fi
58
+ else
59
+ echo " No request-log found"
60
+ fi
61
+
62
+ echo ""
63
+
64
+ # What's in progress (from ready.json)
65
+ echo -e "${YELLOW}🔄 IN PROGRESS${NC}"
66
+ echo "─────────────────────────────────────"
67
+
68
+ if [ -f "$READY_JSON" ]; then
69
+ in_progress=$(python3 -c "
70
+ import json
71
+ with open('$READY_JSON') as f:
72
+ data = json.load(f)
73
+ for task in data.get('inProgress', []):
74
+ if isinstance(task, dict):
75
+ print(f\" • {task.get('id', 'unknown')}: {task.get('title', 'No title')}\")
76
+ else:
77
+ print(f\" • {task}\")
78
+ " 2>/dev/null || echo " Unable to parse ready.json")
79
+
80
+ if [ -n "$in_progress" ]; then
81
+ echo "$in_progress"
82
+ else
83
+ echo " Nothing currently in progress"
84
+ fi
85
+ else
86
+ echo " No ready.json found"
87
+ fi
88
+
89
+ echo ""
90
+
91
+ # What's next (from ready.json)
92
+ echo -e "${CYAN}📋 UP NEXT${NC}"
93
+ echo "─────────────────────────────────────"
94
+
95
+ if [ -f "$READY_JSON" ]; then
96
+ ready=$(python3 -c "
97
+ import json
98
+ with open('$READY_JSON') as f:
99
+ data = json.load(f)
100
+ ready_tasks = data.get('ready', [])[:3] # Top 3
101
+ for task in ready_tasks:
102
+ if isinstance(task, dict):
103
+ print(f\" • {task.get('id', 'unknown')}: {task.get('title', 'No title')}\")
104
+ else:
105
+ print(f\" • {task}\")
106
+ " 2>/dev/null || echo " Unable to parse ready.json")
107
+
108
+ if [ -n "$ready" ]; then
109
+ echo "$ready"
110
+ else
111
+ echo " No tasks ready"
112
+ fi
113
+ fi
114
+
115
+ echo ""
116
+
117
+ # Blockers (from ready.json and progress.md)
118
+ echo -e "${YELLOW}🚧 BLOCKERS${NC}"
119
+ echo "─────────────────────────────────────"
120
+
121
+ has_blockers=false
122
+
123
+ if [ -f "$READY_JSON" ]; then
124
+ blocked=$(python3 -c "
125
+ import json
126
+ with open('$READY_JSON') as f:
127
+ data = json.load(f)
128
+ for task in data.get('blocked', []):
129
+ if isinstance(task, dict):
130
+ print(f\" • {task.get('id', 'unknown')}: {task.get('reason', 'No reason')}\")
131
+ else:
132
+ print(f\" • {task}\")
133
+ " 2>/dev/null || true)
134
+
135
+ if [ -n "$blocked" ]; then
136
+ echo "$blocked"
137
+ has_blockers=true
138
+ fi
139
+ fi
140
+
141
+ if [ "$has_blockers" = false ]; then
142
+ echo " None 🎉"
143
+ fi
144
+
145
+ echo ""
146
+
147
+ # Recent decisions (from feedback-patterns.md)
148
+ if [ -f "$WORKFLOW_DIR/state/feedback-patterns.md" ]; then
149
+ recent_patterns=$(grep "$SINCE" "$WORKFLOW_DIR/state/feedback-patterns.md" 2>/dev/null || true)
150
+ if [ -n "$recent_patterns" ]; then
151
+ echo -e "${CYAN}📝 RECENT DECISIONS${NC}"
152
+ echo "─────────────────────────────────────"
153
+ echo "$recent_patterns"
154
+ echo ""
155
+ fi
156
+ fi
157
+
158
+ echo -e "${CYAN}═══════════════════════════════════════${NC}"
159
+ echo ""
160
+ echo "For full details:"
161
+ echo " • Request log: $REQUEST_LOG"
162
+ echo " • Progress: $PROGRESS_MD"
@@ -0,0 +1,74 @@
1
+ #!/bin/bash
2
+
3
+ # Wogi Flow - Start Task
4
+
5
+ set -e
6
+
7
+ WORKFLOW_DIR=".workflow"
8
+ READY_JSON="$WORKFLOW_DIR/state/ready.json"
9
+
10
+ # Colors
11
+ GREEN='\033[0;32m'
12
+ RED='\033[0;31m'
13
+ NC='\033[0m'
14
+
15
+ if [ -z "$1" ]; then
16
+ echo "Usage: flow start <task-id>"
17
+ exit 1
18
+ fi
19
+
20
+ TASK_ID="$1"
21
+
22
+ if [ ! -f "$READY_JSON" ]; then
23
+ echo -e "${RED}Error: No ready.json found${NC}"
24
+ exit 1
25
+ fi
26
+
27
+ READY_FILE="$READY_JSON" TASK_ID_ARG="$TASK_ID" python3 << 'EOF'
28
+ import json, os
29
+
30
+ task_id = os.environ['TASK_ID_ARG']
31
+ ready_file = os.environ['READY_FILE']
32
+
33
+ with open(ready_file) as f:
34
+ data = json.load(f)
35
+
36
+ # Find task in ready
37
+ ready = data.get('ready', [])
38
+ found = None
39
+ found_idx = None
40
+
41
+ for i, task in enumerate(ready):
42
+ if isinstance(task, dict):
43
+ if task.get('id') == task_id:
44
+ found = task
45
+ found_idx = i
46
+ break
47
+ elif task == task_id:
48
+ found = {'id': task_id}
49
+ found_idx = i
50
+ break
51
+
52
+ if found is None:
53
+ print(f'\033[0;31mTask {task_id} not found in ready queue\033[0m')
54
+ exit(1)
55
+
56
+ # Move to in progress
57
+ ready.pop(found_idx)
58
+ data['ready'] = ready
59
+
60
+ in_progress = data.get('inProgress', [])
61
+ in_progress.append(found)
62
+ data['inProgress'] = in_progress
63
+
64
+ # Update timestamp
65
+ from datetime import datetime
66
+ data['lastUpdated'] = datetime.now().isoformat()
67
+
68
+ with open(ready_file, 'w') as f:
69
+ json.dump(data, f, indent=2)
70
+
71
+ print(f'\033[0;32m✓ Started: {task_id}\033[0m')
72
+ if isinstance(found, dict) and found.get('title'):
73
+ print(f' {found["title"]}')
74
+ EOF
@@ -0,0 +1,235 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Wogi Flow - Start Task
5
+ *
6
+ * Moves a task from ready to inProgress queue.
7
+ * v2.0: Integrates with durable session for crash recovery and suspension support.
8
+ */
9
+
10
+ const {
11
+ PATHS,
12
+ fileExists,
13
+ moveTaskAsync,
14
+ findTask,
15
+ color,
16
+ error,
17
+ getConfig
18
+ } = require('./flow-utils');
19
+ const { getAutoContext, formatAutoContext } = require('./flow-auto-context');
20
+ const { shouldUseMultiApproach, analyzeForMultiApproach, formatAnalysis } = require('./flow-multi-approach');
21
+ const { assessTaskComplexity } = require('./flow-complexity');
22
+
23
+ // v1.7.0 context memory management
24
+ const { warnIfContextHigh, checkContextHealth } = require('./flow-context-monitor');
25
+ const { setCurrentTask } = require('./flow-memory-blocks');
26
+ const { trackTaskStart, checkAndDisplayResumeContext } = require('./flow-session-state');
27
+
28
+ // v2.0 durable session support
29
+ const {
30
+ loadDurableSession,
31
+ createDurableSession,
32
+ createDurableSessionAsync,
33
+ canResumeFromStep,
34
+ getResumeContext,
35
+ getSuspensionStatus,
36
+ resumeSession,
37
+ isSuspended,
38
+ STEP_STATUS
39
+ } = require('./flow-durable-session');
40
+
41
+ async function main() {
42
+ const taskId = process.argv[2];
43
+ const forceResume = process.argv.includes('--force-resume');
44
+ const skipSuspensionCheck = process.argv.includes('--skip-suspension');
45
+
46
+ if (!taskId) {
47
+ console.log('Usage: flow start <task-id> [--force-resume] [--skip-suspension]');
48
+ process.exit(1);
49
+ }
50
+
51
+ // v1.7.0: Check for session resume context
52
+ const config = getConfig();
53
+ if (config.sessionState?.autoRestore !== false) {
54
+ checkAndDisplayResumeContext();
55
+ }
56
+
57
+ // v1.7.0: Check context health at task start
58
+ if (config.contextMonitor?.checkOnSessionStart !== false) {
59
+ warnIfContextHigh();
60
+ }
61
+
62
+ // v2.0: Check for existing durable session for this task
63
+ if (config.durableSteps?.enabled !== false) {
64
+ const existingSession = loadDurableSession();
65
+
66
+ if (existingSession && existingSession.taskId === taskId) {
67
+ // Found existing session for this task - handle resume
68
+ const resumeInfo = canResumeFromStep(existingSession);
69
+ const suspension = getSuspensionStatus();
70
+
71
+ if (suspension && !skipSuspensionCheck) {
72
+ // Task is suspended
73
+ console.log('');
74
+ console.log(color('yellow', '⏸️ Task is SUSPENDED'));
75
+ console.log(color('yellow', '─'.repeat(50)));
76
+ console.log(`Task: ${taskId}`);
77
+ console.log(`Type: ${suspension.type}`);
78
+ console.log(`Reason: ${suspension.reason}`);
79
+ console.log(`Suspended at: ${suspension.suspendedAt}`);
80
+ console.log('');
81
+
82
+ if (suspension.canResume) {
83
+ console.log(color('green', '✓ Resume condition is met!'));
84
+ if (forceResume) {
85
+ console.log('Resuming session...');
86
+ resumeSession({ force: true });
87
+ } else {
88
+ console.log(`Run: ${color('cyan', `flow start ${taskId} --force-resume`)} to continue`);
89
+ process.exit(0);
90
+ }
91
+ } else {
92
+ console.log(color('red', '✗ Resume condition not yet met'));
93
+ console.log(`Reason: ${suspension.resumeReason}`);
94
+ console.log('');
95
+ console.log(`To override: ${color('cyan', `flow start ${taskId} --skip-suspension`)}`);
96
+ process.exit(0);
97
+ }
98
+ }
99
+
100
+ if (resumeInfo.canResume && resumeInfo.completedCount > 0) {
101
+ // Show resume context
102
+ console.log('');
103
+ console.log(color('cyan', '🔄 Resuming from durable session'));
104
+ console.log(color('cyan', '─'.repeat(50)));
105
+ console.log(`Task: ${taskId}`);
106
+ console.log(`Progress: ${resumeInfo.completedCount}/${resumeInfo.totalSteps} steps completed`);
107
+ console.log(`Resuming from: ${resumeInfo.fromStep?.description?.substring(0, 60) || resumeInfo.fromStep?.id}...`);
108
+ console.log(color('cyan', '─'.repeat(50)));
109
+ console.log('');
110
+ }
111
+ } else if (existingSession && existingSession.taskId !== taskId) {
112
+ // Different task in session - block starting new task
113
+ console.log('');
114
+ console.log(color('yellow', '⚠️ Another task is in a durable session'));
115
+ console.log(`Current session: ${existingSession.taskId}`);
116
+ console.log(`Attempting to start: ${taskId}`);
117
+ console.log('');
118
+ console.log(`Finish current task first, or run: ${color('cyan', 'flow session clear')}`);
119
+ console.log('');
120
+ process.exit(1);
121
+ }
122
+ }
123
+
124
+ if (!fileExists(PATHS.ready)) {
125
+ error('No ready.json found');
126
+ process.exit(1);
127
+ }
128
+
129
+ // Check if task exists and where it is
130
+ const found = findTask(taskId);
131
+
132
+ if (!found) {
133
+ console.log(color('red', `Task ${taskId} not found in any queue`));
134
+ process.exit(1);
135
+ }
136
+
137
+ if (found.list === 'inProgress') {
138
+ console.log(color('yellow', `Task ${taskId} is already in progress`));
139
+ process.exit(0);
140
+ }
141
+
142
+ if (found.list !== 'ready') {
143
+ console.log(color('red', `Task ${taskId} is in ${found.list}, not ready`));
144
+ process.exit(1);
145
+ }
146
+
147
+ // Move task from ready to inProgress (with file locking)
148
+ const result = await moveTaskAsync(taskId, 'ready', 'inProgress');
149
+
150
+ if (!result.success) {
151
+ error(result.error);
152
+ process.exit(1);
153
+ }
154
+
155
+ console.log(color('green', `✓ Started: ${taskId}`));
156
+
157
+ const taskTitle = result.task && typeof result.task === 'object' && result.task.title
158
+ ? result.task.title
159
+ : taskId;
160
+
161
+ if (result.task && typeof result.task === 'object' && result.task.title) {
162
+ console.log(` ${result.task.title}`);
163
+ }
164
+
165
+ // v1.7.0: Track task in session state and memory blocks
166
+ try {
167
+ trackTaskStart(taskId, taskTitle);
168
+ setCurrentTask(taskId, taskTitle);
169
+ } catch (err) {
170
+ if (process.env.DEBUG) console.error(`[DEBUG] Task tracking: ${err.message}`);
171
+ }
172
+
173
+ // v2.0: Initialize durable session for crash recovery (with file locking)
174
+ if (config.durableSteps?.enabled !== false) {
175
+ try {
176
+ // Extract acceptance criteria if available
177
+ const acceptanceCriteria = result.task?.acceptanceCriteria || result.task?.scenarios || [];
178
+ const steps = Array.isArray(acceptanceCriteria) ? acceptanceCriteria : [];
179
+ const sessionSteps = steps.length > 0 ? steps : [taskTitle || taskId];
180
+
181
+ // Use async version with file locking to prevent race conditions
182
+ const session = await createDurableSessionAsync(taskId, 'task', sessionSteps);
183
+
184
+ if (steps.length > 0) {
185
+ console.log(color('cyan', `📋 Durable session initialized with ${steps.length} steps`));
186
+ } else if (process.env.DEBUG) {
187
+ console.log(color('cyan', '📋 Durable session initialized (no acceptance criteria)'));
188
+ }
189
+ } catch (err) {
190
+ if (process.env.DEBUG) console.error(`[DEBUG] Durable session init: ${err.message}`);
191
+ }
192
+ }
193
+
194
+ // Auto-context: show relevant files for this task
195
+ const taskDescription = result.task?.title || result.task?.description || taskId;
196
+
197
+ if (config.autoContext?.enabled !== false) {
198
+ try {
199
+ const context = await getAutoContext(taskDescription);
200
+ if (context.files && context.files.length > 0) {
201
+ console.log('');
202
+ console.log(formatAutoContext(context));
203
+ }
204
+ } catch (err) {
205
+ // Auto-context is best-effort; don't block task start on failure
206
+ if (process.env.DEBUG) console.error(`[DEBUG] Auto-context: ${err.message}`);
207
+ }
208
+ }
209
+
210
+ // Multi-approach: suggest for complex tasks
211
+ if (config.multiApproach?.enabled !== false && config.multiApproach?.mode === 'suggest') {
212
+ try {
213
+ const complexity = assessTaskComplexity(taskDescription);
214
+ const decision = shouldUseMultiApproach(complexity.level);
215
+
216
+ if (decision.shouldUse) {
217
+ console.log('');
218
+ console.log(color('yellow', '━'.repeat(50)));
219
+ console.log(color('yellow', '💡 Multi-Approach Suggestion'));
220
+ console.log(color('yellow', '━'.repeat(50)));
221
+ console.log(`This task has "${complexity.level}" complexity.`);
222
+ console.log('Consider using multi-approach validation for better results.');
223
+ console.log(` Run: ${color('cyan', `flow multi-approach --analyze "${taskDescription}"`)}`);
224
+ console.log('');
225
+ }
226
+ } catch {
227
+ // Ignore multi-approach errors
228
+ }
229
+ }
230
+ }
231
+
232
+ main().catch(err => {
233
+ console.error(`Error: ${err.message}`);
234
+ process.exit(1);
235
+ });
@@ -0,0 +1,110 @@
1
+ #!/bin/bash
2
+
3
+ # Wogi Flow - Project Status Overview
4
+
5
+ set -e
6
+
7
+ WORKFLOW_DIR=".workflow"
8
+
9
+ # Colors
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ CYAN='\033[0;36m'
13
+ RED='\033[0;31m'
14
+ NC='\033[0m'
15
+
16
+ echo -e "${CYAN}═══════════════════════════════════════${NC}"
17
+ echo -e "${CYAN} PROJECT STATUS${NC}"
18
+ echo -e "${CYAN}═══════════════════════════════════════${NC}"
19
+ echo ""
20
+
21
+ # Task counts
22
+ if [ -f "$WORKFLOW_DIR/state/ready.json" ]; then
23
+ echo -e "${CYAN}Tasks${NC}"
24
+ READY_FILE="$WORKFLOW_DIR/state/ready.json" python3 << 'EOF'
25
+ import json, os
26
+ with open(os.environ['READY_FILE']) as f:
27
+ data = json.load(f)
28
+ ready = len(data.get('ready', []))
29
+ in_prog = len(data.get('inProgress', []))
30
+ blocked = len(data.get('blocked', []))
31
+ done = len(data.get('recentlyCompleted', []))
32
+ print(f" Ready: {ready}")
33
+ print(f" In Progress: {in_prog}")
34
+ print(f" Blocked: {blocked}")
35
+ print(f" Recently Done: {done}")
36
+ EOF
37
+ echo ""
38
+ fi
39
+
40
+ # Features
41
+ if [ -d "$WORKFLOW_DIR/changes" ]; then
42
+ feature_count=$(find "$WORKFLOW_DIR/changes" -maxdepth 1 -type d | wc -l)
43
+ feature_count=$((feature_count - 1))
44
+ echo -e "${CYAN}Features${NC}"
45
+ echo " Active: $feature_count"
46
+ if [ $feature_count -gt 0 ]; then
47
+ for dir in "$WORKFLOW_DIR/changes"/*/; do
48
+ if [ -d "$dir" ]; then
49
+ name=$(basename "$dir")
50
+ echo " • $name"
51
+ fi
52
+ done
53
+ fi
54
+ echo ""
55
+ fi
56
+
57
+ # Bugs
58
+ if [ -d "$WORKFLOW_DIR/bugs" ]; then
59
+ bug_count=$(ls "$WORKFLOW_DIR/bugs"/*.md 2>/dev/null | wc -l || echo 0)
60
+ echo -e "${CYAN}Bugs${NC}"
61
+ echo " Open: $bug_count"
62
+ echo ""
63
+ fi
64
+
65
+ # Components (from app-map)
66
+ if [ -f "$WORKFLOW_DIR/state/app-map.md" ]; then
67
+ component_count=$(grep -c "^|" "$WORKFLOW_DIR/state/app-map.md" 2>/dev/null || echo 0)
68
+ component_count=$((component_count - 6)) # Subtract headers
69
+ if [ $component_count -lt 0 ]; then component_count=0; fi
70
+ echo -e "${CYAN}Components${NC}"
71
+ echo " Mapped: $component_count"
72
+ echo ""
73
+ fi
74
+
75
+ # Request log entries
76
+ if [ -f "$WORKFLOW_DIR/state/request-log.md" ]; then
77
+ entry_count=$(grep -c "^### R-" "$WORKFLOW_DIR/state/request-log.md" 2>/dev/null || echo 0)
78
+ echo -e "${CYAN}Request Log${NC}"
79
+ echo " Entries: $entry_count"
80
+ echo ""
81
+ fi
82
+
83
+ # Git status
84
+ if [ -d ".git" ]; then
85
+ echo -e "${CYAN}Git${NC}"
86
+ branch=$(git branch --show-current 2>/dev/null || echo "unknown")
87
+ uncommitted=$(git status --porcelain 2>/dev/null | wc -l)
88
+ echo " Branch: $branch"
89
+ echo " Uncommitted: $uncommitted files"
90
+ echo ""
91
+ fi
92
+
93
+ # Config summary
94
+ if [ -f "$WORKFLOW_DIR/config.json" ]; then
95
+ echo -e "${CYAN}Config${NC}"
96
+ CONFIG_FILE="$WORKFLOW_DIR/config.json" python3 << 'EOF'
97
+ import json, os
98
+ with open(os.environ['CONFIG_FILE']) as f:
99
+ config = json.load(f)
100
+ steps = config.get('mandatorySteps', {})
101
+ after_task = steps.get('afterTask', [])
102
+ if after_task:
103
+ print(f" After task: {', '.join(after_task)}")
104
+ else:
105
+ print(" After task: (none)")
106
+ EOF
107
+ fi
108
+
109
+ echo ""
110
+ echo -e "${CYAN}═══════════════════════════════════════${NC}"