wogiflow 1.9.10 → 2.0.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/.claude/settings.json +45 -12
- package/.workflow/lib/assumption-detector.js +4 -481
- package/.workflow/lib/config-substitution.js +4 -389
- package/.workflow/lib/failure-categories.js +4 -478
- package/lib/commands/login.js +6 -6
- package/lib/commands/logout.js +1 -1
- package/lib/commands/team-connection.js +8 -8
- package/lib/installer.js +19 -20
- package/lib/release-channel.js +2 -2
- package/lib/skill-registry.js +4 -4
- package/lib/upgrader.js +4 -3
- package/lib/utils.js +4 -4
- package/package.json +8 -1
- package/scripts/flow +3 -0
- package/scripts/flow-adaptive-learning.js +19 -36
- package/scripts/flow-aggregate.js +5 -5
- package/scripts/flow-api-index.js +3 -3
- package/scripts/flow-assumption-detector.js +483 -0
- package/scripts/flow-audit.js +6 -6
- package/scripts/flow-auto-context.js +18 -17
- package/scripts/flow-auto-learn.js +5 -5
- package/scripts/flow-background.js +6 -7
- package/scripts/flow-best-of-n.js +1 -1
- package/scripts/flow-bridge-state.js +7 -7
- package/scripts/flow-bridge.js +8 -7
- package/scripts/flow-bug.js +3 -3
- package/scripts/flow-bulk-loop.js +21 -24
- package/scripts/flow-bulk-orchestrator.js +28 -28
- package/scripts/flow-capture.js +8 -8
- package/scripts/flow-cascade-completion.js +512 -0
- package/scripts/flow-cascade.js +2 -2
- package/scripts/flow-checkpoint.js +13 -12
- package/scripts/flow-clarifying-questions.js +4 -4
- package/scripts/flow-cli.js +9 -8
- package/scripts/flow-code-intelligence.js +11 -17
- package/scripts/flow-community-sync.js +2 -2
- package/scripts/flow-community.js +36 -36
- package/scripts/flow-config-defaults.js +14 -6
- package/scripts/flow-config-interactive.js +3 -3
- package/scripts/flow-config-loader.js +30 -61
- package/scripts/flow-config-set.js +2 -2
- package/scripts/flow-config-substitution.js +392 -0
- package/scripts/flow-conflict-resolver.js +7 -68
- package/scripts/flow-consistency-check.js +2 -2
- package/scripts/flow-constants.js +34 -30
- package/scripts/flow-context-compact/expander.js +3 -3
- package/scripts/flow-context-compact/index.js +4 -4
- package/scripts/flow-context-compact/section-extractor.js +1 -1
- package/scripts/flow-context-compact/summary-tree.js +6 -6
- package/scripts/flow-context-estimator.js +23 -18
- package/scripts/flow-context-gatherer.js +2 -2
- package/scripts/flow-context-generator.js +3 -3
- package/scripts/flow-context-init.js +11 -9
- package/scripts/flow-context-monitor.js +5 -5
- package/scripts/flow-context-orchestrator.js +1 -1
- package/scripts/flow-context-scoring.js +8 -8
- package/scripts/flow-correct.js +6 -6
- package/scripts/flow-correction-detector.js +3 -3
- package/scripts/flow-damage-control.js +14 -3
- package/scripts/flow-decision-tracker.js +2 -2
- package/scripts/flow-decisions-merge.js +4 -4
- package/scripts/flow-diff.js +16 -11
- package/scripts/flow-done.js +135 -558
- package/scripts/flow-durable-session.js +7 -6
- package/scripts/flow-entropy-monitor.js +4 -3
- package/scripts/flow-epics.js +4 -5
- package/scripts/flow-error-recovery.js +2 -2
- package/scripts/flow-eval-judge.js +3 -3
- package/scripts/flow-eval.js +8 -8
- package/scripts/flow-export-profile +3 -3
- package/scripts/flow-export-scanner.js +7 -7
- package/scripts/flow-extraction-review.js +3 -12
- package/scripts/flow-failure-categories.js +480 -0
- package/scripts/flow-failure-learning.js +3 -3
- package/scripts/flow-feature.js +3 -3
- package/scripts/flow-figma-confirm.js +11 -7
- package/scripts/flow-figma-extract.js +3 -3
- package/scripts/flow-figma-generate.js +17 -13
- package/scripts/flow-figma-index.js +18 -23
- package/scripts/flow-figma-match.js +6 -5
- package/scripts/flow-figma-mcp-server.js +6 -13
- package/scripts/flow-figma-orchestrator.js +2 -2
- package/scripts/flow-figma-registry.js +2 -2
- package/scripts/flow-function-index.js +3 -3
- package/scripts/flow-gate-confidence.js +2 -2
- package/scripts/flow-gitignore.js +3 -3
- package/scripts/flow-guided-edit.js +13 -21
- package/scripts/flow-health.js +96 -99
- package/scripts/flow-hooks-install.js +3 -3
- package/scripts/flow-hooks.js +25 -27
- package/scripts/flow-http-client.js +2 -2
- package/scripts/flow-hybrid-detect.js +2 -2
- package/scripts/flow-hybrid-interactive.js +7 -6
- package/scripts/flow-hybrid-test.js +6 -6
- package/scripts/flow-hypothesis-generator.js +14 -13
- package/scripts/flow-import-profile +1 -1
- package/scripts/flow-instruction-richness.js +8 -8
- package/scripts/flow-io.js +16 -16
- package/scripts/flow-knowledge-router.js +12 -11
- package/scripts/flow-knowledge-sync.js +14 -20
- package/scripts/flow-links.js +13 -20
- package/scripts/flow-log-manager.js +5 -5
- package/scripts/flow-long-input-chunking.js +32 -56
- package/scripts/flow-long-input-cli.js +3066 -0
- package/scripts/flow-long-input-complexity.js +422 -0
- package/scripts/flow-long-input-constants.js +445 -0
- package/scripts/flow-long-input-detection.js +757 -0
- package/scripts/flow-long-input-stories.js +2 -2
- package/scripts/flow-long-input-voice.js +390 -0
- package/scripts/flow-long-input.js +117 -4845
- package/scripts/flow-loop-retry-learning.js +54 -66
- package/scripts/flow-lsp.js +3 -3
- package/scripts/flow-mcp-docs.js +8 -10
- package/scripts/flow-memory-blocks.js +3 -3
- package/scripts/flow-memory-compactor.js +4 -10
- package/scripts/flow-memory-db.js +6 -5
- package/scripts/flow-memory-sync.js +5 -14
- package/scripts/flow-metrics.js +8 -12
- package/scripts/flow-migrate.js +11 -17
- package/scripts/flow-model-adapter.js +8 -16
- package/scripts/flow-model-caller.js +1 -1
- package/scripts/flow-model-config.js +9 -9
- package/scripts/flow-model-profile.js +3 -3
- package/scripts/flow-model-router.js +1 -1
- package/scripts/flow-model-types.js +2 -2
- package/scripts/flow-models.js +2 -2
- package/scripts/flow-morning.js +10 -10
- package/scripts/flow-multi-approach.js +8 -7
- package/scripts/flow-orchestrate-context.js +793 -0
- package/scripts/flow-orchestrate-llm.js +2 -2
- package/scripts/flow-orchestrate-rollback.js +108 -0
- package/scripts/flow-orchestrate-state.js +323 -0
- package/scripts/flow-orchestrate-templates.js +253 -0
- package/scripts/flow-orchestrate-validation.js +3 -3
- package/scripts/flow-orchestrate-validator.js +176 -0
- package/scripts/flow-orchestrate.js +323 -1848
- package/scripts/flow-output.js +9 -0
- package/scripts/flow-parallel.js +6 -6
- package/scripts/flow-paths.js +28 -9
- package/scripts/flow-pattern-enforcer.js +4 -4
- package/scripts/flow-pattern-extractor.js +23 -34
- package/scripts/flow-peer-review.js +4 -4
- package/scripts/flow-permissions.js +8 -10
- package/scripts/flow-phased-task.js +2 -2
- package/scripts/flow-plan.js +3 -3
- package/scripts/flow-plugin-registry.js +2 -2
- package/scripts/flow-prd-manager.js +2 -2
- package/scripts/flow-proactive-compact.js +1 -1
- package/scripts/flow-product-scanner.js +2 -2
- package/scripts/flow-progress.js +1 -1
- package/scripts/flow-project-analyzer.js +10 -10
- package/scripts/flow-prompt-capture.js +3 -3
- package/scripts/flow-prompt-composer.js +4 -4
- package/scripts/flow-prompt-template.js +3 -3
- package/scripts/flow-providers.js +23 -22
- package/scripts/flow-queue.js +10 -10
- package/scripts/flow-ready.js +4 -7
- package/scripts/flow-registry-manager.js +3 -3
- package/scripts/flow-regression.js +15 -14
- package/scripts/flow-research-protocol.js +2 -2
- package/scripts/flow-response-parser.js +4 -4
- package/scripts/flow-resume.js +6 -6
- package/scripts/flow-review-passes/index.js +11 -8
- package/scripts/flow-review-passes/integration.js +1 -1
- package/scripts/flow-review-passes/logic.js +1 -1
- package/scripts/flow-review-passes/security.js +11 -32
- package/scripts/flow-review-passes/structure.js +2 -2
- package/scripts/flow-review.js +10 -13
- package/scripts/flow-revision-tracker.js +2 -2
- package/scripts/flow-roadmap.js +24 -23
- package/scripts/flow-rules-sync.js +2 -2
- package/scripts/flow-run-trace.js +24 -38
- package/scripts/flow-safety.js +7 -6
- package/scripts/flow-scanner-base.js +3 -3
- package/scripts/flow-scenario-engine.js +55 -54
- package/scripts/flow-script-resolver.js +8 -22
- package/scripts/flow-section-index.js +5 -5
- package/scripts/flow-security.js +148 -4
- package/scripts/flow-semantic-match.js +2 -2
- package/scripts/flow-session-end.js +22 -22
- package/scripts/flow-session-learning.js +3 -3
- package/scripts/flow-session-state.js +2 -2
- package/scripts/flow-setup-hooks.js +13 -16
- package/scripts/flow-skill-create.js +11 -8
- package/scripts/flow-skill-freshness.js +3 -3
- package/scripts/flow-skill-generator.js +27 -24
- package/scripts/flow-skill-learn.js +4 -4
- package/scripts/flow-skill-matcher.js +4 -3
- package/scripts/flow-solution-optimizer.js +5 -11
- package/scripts/flow-spec-generator.js +19 -22
- package/scripts/flow-spec-verifier.js +5 -5
- package/scripts/flow-stack-wizard.js +12 -21
- package/scripts/flow-standards-checker.js +3 -3
- package/scripts/flow-standards-gate.js +2 -2
- package/scripts/flow-standards-learner.js +4 -4
- package/scripts/flow-start.js +14 -13
- package/scripts/flow-state-cleanup.js +2 -2
- package/scripts/flow-stats-collector.js +2 -2
- package/scripts/flow-status.js +5 -6
- package/scripts/flow-statusline-setup.js +13 -11
- package/scripts/flow-step-changelog.js +2 -2
- package/scripts/flow-step-comments.js +2 -2
- package/scripts/flow-step-complexity.js +2 -2
- package/scripts/flow-step-coverage.js +9 -7
- package/scripts/flow-step-knowledge.js +2 -2
- package/scripts/flow-step-pr-tests.js +4 -8
- package/scripts/flow-step-regression.js +2 -2
- package/scripts/flow-step-review.js +2 -2
- package/scripts/flow-step-security.js +9 -14
- package/scripts/flow-step-silent-failures.js +2 -2
- package/scripts/flow-step-simplifier.js +2 -2
- package/scripts/flow-story.js +12 -11
- package/scripts/flow-strict-adherence.js +2 -2
- package/scripts/flow-suspend.js +2 -2
- package/scripts/flow-sync-anonymizer.js +1 -1
- package/scripts/flow-task-analyzer.js +2 -2
- package/scripts/flow-task-checkpoint.js +9 -10
- package/scripts/flow-task-classifier.js +2 -2
- package/scripts/flow-task-completion-summary.js +18 -18
- package/scripts/flow-task-enforcer.js +6 -6
- package/scripts/flow-tech-debt.js +7 -6
- package/scripts/flow-template-extractor.js +10 -18
- package/scripts/flow-templates.js +7 -12
- package/scripts/flow-test-api.js +3 -3
- package/scripts/flow-test-discovery.js +6 -7
- package/scripts/flow-test-generate.js +2 -2
- package/scripts/flow-test-integrity.js +2 -2
- package/scripts/flow-test-ui.js +5 -5
- package/scripts/flow-testing-deps.js +3 -3
- package/scripts/flow-tiered-learning.js +2 -2
- package/scripts/flow-todowrite-sync.js +2 -2
- package/scripts/flow-utils.js +32 -473
- package/scripts/flow-verification-profile.js +32 -35
- package/scripts/flow-verify.js +39 -50
- package/scripts/flow-version-check.js +24 -34
- package/scripts/flow-webmcp-generator.js +11 -6
- package/scripts/flow-wiring-verifier.js +3 -3
- package/scripts/flow-workflow-steps.js +2 -2
- package/scripts/flow-workflow.js +13 -11
- package/scripts/flow-worktree.js +11 -11
- package/scripts/hooks/adapters/claude-code.js +37 -5
- package/scripts/hooks/core/component-check.js +5 -6
- package/scripts/hooks/core/config-change.js +4 -4
- package/scripts/hooks/core/instructions-loaded.js +9 -9
- package/scripts/hooks/core/loop-check.js +6 -6
- package/scripts/hooks/core/observation-capture.js +2 -2
- package/scripts/hooks/core/phase-gate.js +2 -2
- package/scripts/hooks/core/post-compact.js +143 -0
- package/scripts/hooks/core/research-gate.js +2 -2
- package/scripts/hooks/core/routing-gate.js +7 -7
- package/scripts/hooks/core/scope-gate.js +2 -17
- package/scripts/hooks/core/session-context.js +28 -16
- package/scripts/hooks/core/session-end.js +34 -2
- package/scripts/hooks/core/setup-check.js +2 -2
- package/scripts/hooks/core/task-completed.js +8 -8
- package/scripts/hooks/core/task-gate.js +5 -5
- package/scripts/hooks/core/validation.js +5 -5
- package/scripts/hooks/core/worktree-lifecycle.js +3 -3
- package/scripts/hooks/entry/claude-code/config-change.js +3 -8
- package/scripts/hooks/entry/claude-code/instructions-loaded.js +3 -12
- package/scripts/hooks/entry/claude-code/post-compact.js +45 -0
- package/scripts/hooks/entry/claude-code/post-tool-use.js +1 -1
- package/scripts/hooks/entry/claude-code/pre-tool-use.js +65 -1
- package/scripts/hooks/entry/claude-code/session-end.js +3 -7
- package/scripts/hooks/entry/claude-code/session-start.js +8 -4
- package/scripts/hooks/entry/claude-code/setup.js +3 -7
- package/scripts/hooks/entry/claude-code/stop.js +3 -17
- package/scripts/hooks/entry/claude-code/task-completed.js +3 -8
- package/scripts/hooks/entry/claude-code/user-prompt-submit.js +6 -19
- package/scripts/hooks/entry/claude-code/worktree-create.js +3 -7
- package/scripts/hooks/entry/claude-code/worktree-remove.js +3 -7
- package/scripts/hooks/git/post-commit.js +5 -4
- package/scripts/postinstall.js +97 -4
- package/scripts/preuninstall.js +2 -2
- package/scripts/registries/component-registry.js +4 -3
- package/scripts/registries/schema-registry.js +5 -5
- package/scripts/registries/service-registry.js +6 -6
package/.claude/settings.json
CHANGED
|
@@ -11,17 +11,6 @@
|
|
|
11
11
|
]
|
|
12
12
|
}
|
|
13
13
|
],
|
|
14
|
-
"Setup": [
|
|
15
|
-
{
|
|
16
|
-
"hooks": [
|
|
17
|
-
{
|
|
18
|
-
"type": "command",
|
|
19
|
-
"command": "node scripts/hooks/entry/claude-code/setup.js",
|
|
20
|
-
"timeout": 30
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
}
|
|
24
|
-
],
|
|
25
14
|
"UserPromptSubmit": [
|
|
26
15
|
{
|
|
27
16
|
"hooks": [
|
|
@@ -89,6 +78,28 @@
|
|
|
89
78
|
]
|
|
90
79
|
}
|
|
91
80
|
],
|
|
81
|
+
"WorktreeCreate": [
|
|
82
|
+
{
|
|
83
|
+
"hooks": [
|
|
84
|
+
{
|
|
85
|
+
"type": "command",
|
|
86
|
+
"command": "node scripts/hooks/entry/claude-code/worktree-create.js",
|
|
87
|
+
"timeout": 10
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
"WorktreeRemove": [
|
|
93
|
+
{
|
|
94
|
+
"hooks": [
|
|
95
|
+
{
|
|
96
|
+
"type": "command",
|
|
97
|
+
"command": "node scripts/hooks/entry/claude-code/worktree-remove.js",
|
|
98
|
+
"timeout": 5
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
],
|
|
92
103
|
"ConfigChange": [
|
|
93
104
|
{
|
|
94
105
|
"hooks": [
|
|
@@ -99,9 +110,31 @@
|
|
|
99
110
|
}
|
|
100
111
|
]
|
|
101
112
|
}
|
|
113
|
+
],
|
|
114
|
+
"InstructionsLoaded": [
|
|
115
|
+
{
|
|
116
|
+
"hooks": [
|
|
117
|
+
{
|
|
118
|
+
"type": "command",
|
|
119
|
+
"command": "node scripts/hooks/entry/claude-code/instructions-loaded.js",
|
|
120
|
+
"timeout": 5
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
"PostCompact": [
|
|
126
|
+
{
|
|
127
|
+
"hooks": [
|
|
128
|
+
{
|
|
129
|
+
"type": "command",
|
|
130
|
+
"command": "node scripts/hooks/entry/claude-code/post-compact.js",
|
|
131
|
+
"timeout": 5
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
}
|
|
102
135
|
]
|
|
103
136
|
},
|
|
104
137
|
"_wogiFlowManaged": true,
|
|
105
|
-
"_wogiFlowVersion": "1.
|
|
138
|
+
"_wogiFlowVersion": "1.9.10",
|
|
106
139
|
"_comment": "Shared WogiFlow hook configuration. Committed to repo for team use. User-specific overrides go in settings.local.json."
|
|
107
140
|
}
|
|
@@ -1,481 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* Used by spec generation to surface assumptions for user validation.
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Detects implicit assumptions in task descriptions
|
|
9
|
-
* - Assigns confidence levels (0.0 - 1.0)
|
|
10
|
-
* - Categorizes by type (technical, requirements, scope, behavior)
|
|
11
|
-
* - Flags low-confidence assumptions for clarification
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
// Assumption categories
|
|
15
|
-
const ASSUMPTION_CATEGORIES = {
|
|
16
|
-
TECHNICAL: 'technical', // Tech stack, framework, patterns
|
|
17
|
-
REQUIREMENTS: 'requirements', // User requirements, acceptance criteria
|
|
18
|
-
SCOPE: 'scope', // Task boundaries, what's included/excluded
|
|
19
|
-
BEHAVIOR: 'behavior', // Expected behavior, edge cases
|
|
20
|
-
DEPENDENCIES: 'dependencies', // Dependencies on other components/tasks
|
|
21
|
-
DATA: 'data', // Data format, structure, validation
|
|
22
|
-
UI: 'ui', // User interface expectations
|
|
23
|
-
SECURITY: 'security', // Security requirements
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// Confidence thresholds
|
|
27
|
-
const CONFIDENCE = {
|
|
28
|
-
HIGH: 0.9, // Very confident, based on explicit info
|
|
29
|
-
MEDIUM: 0.7, // Reasonably confident, common pattern
|
|
30
|
-
LOW: 0.5, // Uncertain, needs clarification
|
|
31
|
-
GUESS: 0.3, // Wild guess, definitely needs clarification
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
// Threshold for flagging assumptions
|
|
35
|
-
const CLARIFICATION_THRESHOLD = 0.7;
|
|
36
|
-
|
|
37
|
-
// Max input size before skipping pattern matching (ReDoS protection)
|
|
38
|
-
const MAX_INPUT_SIZE = 100000; // 100KB
|
|
39
|
-
|
|
40
|
-
// Unicode characters for confidence bar display
|
|
41
|
-
const CONFIDENCE_FILLED = '\u25CF'; // ●
|
|
42
|
-
const CONFIDENCE_EMPTY = '\u25CB'; // ○
|
|
43
|
-
|
|
44
|
-
// Detection patterns - defined at module scope for performance
|
|
45
|
-
const FRAMEWORK_PATTERNS = [
|
|
46
|
-
{ pattern: /component|react|vue|angular|svelte/i, assumption: 'Using existing component framework', confidence: 0.9 },
|
|
47
|
-
{ pattern: /api|endpoint|rest|graphql/i, assumption: 'Following existing API patterns', confidence: 0.7 },
|
|
48
|
-
{ pattern: /database|db|query|model/i, assumption: 'Using existing database patterns', confidence: 0.7 },
|
|
49
|
-
{ pattern: /auth|login|session|token/i, assumption: 'Integrating with existing auth system', confidence: 0.7 },
|
|
50
|
-
];
|
|
51
|
-
|
|
52
|
-
const AMBIGUOUS_TERMS = [
|
|
53
|
-
{ term: 'integrate', question: 'What system/service should this integrate with?' },
|
|
54
|
-
{ term: 'connect', question: 'What should this connect to?' },
|
|
55
|
-
{ term: 'similar to', question: 'Which existing feature should this be similar to?' },
|
|
56
|
-
{ term: 'like', question: 'What exactly should this be like?' },
|
|
57
|
-
];
|
|
58
|
-
|
|
59
|
-
const SCOPE_PATTERNS = [
|
|
60
|
-
{ pattern: /all|every|each/i, assumption: 'Scope includes all instances', confidence: 0.5 },
|
|
61
|
-
{ pattern: /complete|full|entire/i, assumption: 'Full implementation required (not partial)', confidence: 0.7 },
|
|
62
|
-
{ pattern: /basic|simple|minimal/i, assumption: 'MVP scope only (no edge cases)', confidence: 0.7 },
|
|
63
|
-
{ pattern: /update|modify|change/i, assumption: 'Updating existing feature (not creating new)', confidence: 0.7 },
|
|
64
|
-
];
|
|
65
|
-
|
|
66
|
-
const VAGUE_PATTERNS = [
|
|
67
|
-
{ pattern: /should work|should be able/i, text: 'Specific success criteria undefined', confidence: 0.5 },
|
|
68
|
-
{ pattern: /nice to have|optional/i, text: 'Optional features may be deferred', confidence: 0.7 },
|
|
69
|
-
{ pattern: /as needed|when necessary/i, text: 'Trigger conditions are understood', confidence: 0.5 },
|
|
70
|
-
{ pattern: /appropriate|suitable/i, text: '"Appropriate" behavior is understood', confidence: 0.5 },
|
|
71
|
-
];
|
|
72
|
-
|
|
73
|
-
// UI detection patterns
|
|
74
|
-
const UI_ELEMENT_PATTERN = /button|form|modal|dialog|page|screen|view/i;
|
|
75
|
-
const UI_LAYOUT_PATTERN = /layout|position|place|where/i;
|
|
76
|
-
const UI_STYLING_PATTERN = /style|design|color|theme/i;
|
|
77
|
-
const RESPONSIVE_PATTERN = /responsive|mobile|desktop/i;
|
|
78
|
-
|
|
79
|
-
// Data detection patterns
|
|
80
|
-
const DATA_PATTERN = /data|input|field|form/i;
|
|
81
|
-
const FORMAT_PATTERN = /format|type|valid/i;
|
|
82
|
-
const PERSISTENCE_PATTERN = /save|store|persist|database/i;
|
|
83
|
-
|
|
84
|
-
// Behavior detection patterns
|
|
85
|
-
const ASYNC_PATTERN = /fetch|load|api|async/i;
|
|
86
|
-
const LOADING_PATTERN = /loading|spinner/i;
|
|
87
|
-
const EDGE_CASE_PATTERN = /edge case|empty|null|undefined|invalid/i;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Assumption object structure
|
|
91
|
-
* @typedef {Object} Assumption
|
|
92
|
-
* @property {string} id - Unique identifier
|
|
93
|
-
* @property {string} text - The assumption statement
|
|
94
|
-
* @property {string} category - One of ASSUMPTION_CATEGORIES
|
|
95
|
-
* @property {number} confidence - 0.0 to 1.0
|
|
96
|
-
* @property {string} source - What triggered this assumption
|
|
97
|
-
* @property {string} clarificationQuestion - Question to ask user if low confidence
|
|
98
|
-
* @property {boolean} needsClarification - Whether user should validate
|
|
99
|
-
*/
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Detect assumptions from task description and context
|
|
103
|
-
* @param {Object} params - Detection parameters
|
|
104
|
-
* @param {string} params.title - Task title
|
|
105
|
-
* @param {string} params.description - Full task description
|
|
106
|
-
* @param {string[]} params.acceptanceCriteria - List of acceptance criteria
|
|
107
|
-
* @param {Object} params.context - Additional context (app-map, decisions, etc.)
|
|
108
|
-
* @returns {Assumption[]} Array of detected assumptions
|
|
109
|
-
*/
|
|
110
|
-
function detectAssumptions(params) {
|
|
111
|
-
const { title, description, acceptanceCriteria = [], context = {} } = params;
|
|
112
|
-
const assumptions = [];
|
|
113
|
-
|
|
114
|
-
// ReDoS protection: check total input size before pattern matching
|
|
115
|
-
const totalInputSize = (title?.length || 0) +
|
|
116
|
-
(description?.length || 0) +
|
|
117
|
-
acceptanceCriteria.reduce((sum, c) => sum + (c?.length || 0), 0);
|
|
118
|
-
|
|
119
|
-
if (totalInputSize > MAX_INPUT_SIZE) {
|
|
120
|
-
console.warn(`[assumption-detector] Input too large (${totalInputSize} chars), skipping pattern matching`);
|
|
121
|
-
return [{
|
|
122
|
-
id: 'A01',
|
|
123
|
-
text: 'Input too large for detailed analysis',
|
|
124
|
-
category: ASSUMPTION_CATEGORIES.SCOPE,
|
|
125
|
-
confidence: CONFIDENCE.LOW,
|
|
126
|
-
source: 'size_limit',
|
|
127
|
-
clarificationQuestion: 'Please provide a more concise description for detailed analysis',
|
|
128
|
-
needsClarification: true
|
|
129
|
-
}];
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// 1. Detect technical assumptions
|
|
133
|
-
assumptions.push(...detectTechnicalAssumptions(title, description, context));
|
|
134
|
-
|
|
135
|
-
// 2. Detect scope assumptions
|
|
136
|
-
assumptions.push(...detectScopeAssumptions(title, description, acceptanceCriteria));
|
|
137
|
-
|
|
138
|
-
// 3. Detect requirements assumptions
|
|
139
|
-
assumptions.push(...detectRequirementsAssumptions(description, acceptanceCriteria));
|
|
140
|
-
|
|
141
|
-
// 4. Detect UI assumptions
|
|
142
|
-
assumptions.push(...detectUIAssumptions(title, description));
|
|
143
|
-
|
|
144
|
-
// 5. Detect data assumptions
|
|
145
|
-
assumptions.push(...detectDataAssumptions(description, acceptanceCriteria));
|
|
146
|
-
|
|
147
|
-
// 6. Detect behavior assumptions
|
|
148
|
-
assumptions.push(...detectBehaviorAssumptions(description, acceptanceCriteria));
|
|
149
|
-
|
|
150
|
-
// Deduplicate and assign IDs
|
|
151
|
-
const uniqueAssumptions = deduplicateAssumptions(assumptions);
|
|
152
|
-
return uniqueAssumptions.map((a, i) => ({
|
|
153
|
-
...a,
|
|
154
|
-
id: `A${String(i + 1).padStart(2, '0')}`,
|
|
155
|
-
needsClarification: a.confidence < CLARIFICATION_THRESHOLD,
|
|
156
|
-
}));
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Detect technical assumptions (framework, patterns, etc.)
|
|
161
|
-
*/
|
|
162
|
-
function detectTechnicalAssumptions(title, description, context) {
|
|
163
|
-
const assumptions = [];
|
|
164
|
-
const text = `${title} ${description}`.toLowerCase();
|
|
165
|
-
|
|
166
|
-
// Framework assumptions - use module-level patterns
|
|
167
|
-
for (const { pattern, assumption, confidence } of FRAMEWORK_PATTERNS) {
|
|
168
|
-
if (pattern.test(text)) {
|
|
169
|
-
assumptions.push({
|
|
170
|
-
text: assumption,
|
|
171
|
-
category: ASSUMPTION_CATEGORIES.TECHNICAL,
|
|
172
|
-
confidence,
|
|
173
|
-
source: 'keyword_detection',
|
|
174
|
-
clarificationQuestion: `Should this ${assumption.toLowerCase()}?`,
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Check for ambiguous technical terms - use module-level patterns
|
|
180
|
-
for (const { term, question } of AMBIGUOUS_TERMS) {
|
|
181
|
-
if (text.includes(term)) {
|
|
182
|
-
assumptions.push({
|
|
183
|
-
text: `Integration approach for "${term}" is understood`,
|
|
184
|
-
category: ASSUMPTION_CATEGORIES.TECHNICAL,
|
|
185
|
-
confidence: CONFIDENCE.LOW,
|
|
186
|
-
source: 'ambiguous_term',
|
|
187
|
-
clarificationQuestion: question,
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return assumptions;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Detect scope assumptions (what's included/excluded)
|
|
197
|
-
*/
|
|
198
|
-
function detectScopeAssumptions(title, description, acceptanceCriteria) {
|
|
199
|
-
const assumptions = [];
|
|
200
|
-
const text = `${title} ${description}`.toLowerCase();
|
|
201
|
-
const criteriaText = acceptanceCriteria.join(' ').toLowerCase();
|
|
202
|
-
|
|
203
|
-
// Scope-expanding keywords - use module-level patterns
|
|
204
|
-
for (const { pattern, assumption, confidence } of SCOPE_PATTERNS) {
|
|
205
|
-
if (pattern.test(text)) {
|
|
206
|
-
assumptions.push({
|
|
207
|
-
text: assumption,
|
|
208
|
-
category: ASSUMPTION_CATEGORIES.SCOPE,
|
|
209
|
-
confidence,
|
|
210
|
-
source: 'scope_keyword',
|
|
211
|
-
clarificationQuestion: `Is this assumption correct: "${assumption}"?`,
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Check if error handling is mentioned
|
|
217
|
-
if (!criteriaText.includes('error') && !text.includes('error')) {
|
|
218
|
-
assumptions.push({
|
|
219
|
-
text: 'Error handling will follow existing patterns',
|
|
220
|
-
category: ASSUMPTION_CATEGORIES.SCOPE,
|
|
221
|
-
confidence: CONFIDENCE.MEDIUM,
|
|
222
|
-
source: 'missing_error_handling',
|
|
223
|
-
clarificationQuestion: 'Should specific error handling be implemented?',
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return assumptions;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Detect requirements assumptions
|
|
232
|
-
*/
|
|
233
|
-
function detectRequirementsAssumptions(description, acceptanceCriteria) {
|
|
234
|
-
const assumptions = [];
|
|
235
|
-
|
|
236
|
-
// Check for vague requirements - use module-level patterns
|
|
237
|
-
for (const { pattern, text, confidence } of VAGUE_PATTERNS) {
|
|
238
|
-
if (pattern.test(description)) {
|
|
239
|
-
assumptions.push({
|
|
240
|
-
text,
|
|
241
|
-
category: ASSUMPTION_CATEGORIES.REQUIREMENTS,
|
|
242
|
-
confidence,
|
|
243
|
-
source: 'vague_requirement',
|
|
244
|
-
clarificationQuestion: `Please clarify: ${text.toLowerCase()}`,
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Check if acceptance criteria are specific enough (require Given AND When AND Then)
|
|
250
|
-
for (const criterion of acceptanceCriteria) {
|
|
251
|
-
const hasGiven = criterion.includes('Given');
|
|
252
|
-
const hasWhen = criterion.includes('When');
|
|
253
|
-
const hasThen = criterion.includes('Then');
|
|
254
|
-
|
|
255
|
-
if (!(hasGiven && hasWhen && hasThen)) {
|
|
256
|
-
assumptions.push({
|
|
257
|
-
text: `Acceptance criteria "${criterion.slice(0, 30)}..." is understood`,
|
|
258
|
-
category: ASSUMPTION_CATEGORIES.REQUIREMENTS,
|
|
259
|
-
confidence: CONFIDENCE.MEDIUM,
|
|
260
|
-
source: 'non_gherkin_criteria',
|
|
261
|
-
clarificationQuestion: 'Can you provide Given/When/Then format for this criteria?',
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
return assumptions;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Detect UI assumptions
|
|
271
|
-
*/
|
|
272
|
-
function detectUIAssumptions(title, description) {
|
|
273
|
-
const assumptions = [];
|
|
274
|
-
const text = `${title} ${description}`.toLowerCase();
|
|
275
|
-
|
|
276
|
-
// UI-related keywords - use module-level patterns
|
|
277
|
-
if (UI_ELEMENT_PATTERN.test(text)) {
|
|
278
|
-
// Check for layout assumptions
|
|
279
|
-
if (!UI_LAYOUT_PATTERN.test(text)) {
|
|
280
|
-
assumptions.push({
|
|
281
|
-
text: 'UI placement follows existing patterns',
|
|
282
|
-
category: ASSUMPTION_CATEGORIES.UI,
|
|
283
|
-
confidence: CONFIDENCE.MEDIUM,
|
|
284
|
-
source: 'ui_placement',
|
|
285
|
-
clarificationQuestion: 'Where should this UI element be placed?',
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// Check for styling assumptions
|
|
290
|
-
if (!UI_STYLING_PATTERN.test(text)) {
|
|
291
|
-
assumptions.push({
|
|
292
|
-
text: 'Styling will match existing design system',
|
|
293
|
-
category: ASSUMPTION_CATEGORIES.UI,
|
|
294
|
-
confidence: CONFIDENCE.HIGH,
|
|
295
|
-
source: 'ui_styling',
|
|
296
|
-
clarificationQuestion: 'Should this follow existing design system?',
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// Responsive design - use module-level pattern
|
|
302
|
-
if (RESPONSIVE_PATTERN.test(text)) {
|
|
303
|
-
assumptions.push({
|
|
304
|
-
text: 'Responsive breakpoints follow existing patterns',
|
|
305
|
-
category: ASSUMPTION_CATEGORIES.UI,
|
|
306
|
-
confidence: CONFIDENCE.MEDIUM,
|
|
307
|
-
source: 'responsive_design',
|
|
308
|
-
clarificationQuestion: 'What screen sizes should be supported?',
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return assumptions;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Detect data-related assumptions
|
|
317
|
-
*/
|
|
318
|
-
function detectDataAssumptions(description, acceptanceCriteria) {
|
|
319
|
-
const assumptions = [];
|
|
320
|
-
const text = `${description} ${acceptanceCriteria.join(' ')}`.toLowerCase();
|
|
321
|
-
|
|
322
|
-
// Data format assumptions - use module-level patterns
|
|
323
|
-
if (DATA_PATTERN.test(text)) {
|
|
324
|
-
if (!FORMAT_PATTERN.test(text)) {
|
|
325
|
-
assumptions.push({
|
|
326
|
-
text: 'Data validation follows existing patterns',
|
|
327
|
-
category: ASSUMPTION_CATEGORIES.DATA,
|
|
328
|
-
confidence: CONFIDENCE.MEDIUM,
|
|
329
|
-
source: 'data_validation',
|
|
330
|
-
clarificationQuestion: 'What validation rules should be applied?',
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// Persistence assumptions - use module-level pattern
|
|
336
|
-
if (PERSISTENCE_PATTERN.test(text)) {
|
|
337
|
-
assumptions.push({
|
|
338
|
-
text: 'Data persistence uses existing storage patterns',
|
|
339
|
-
category: ASSUMPTION_CATEGORIES.DATA,
|
|
340
|
-
confidence: CONFIDENCE.MEDIUM,
|
|
341
|
-
source: 'data_persistence',
|
|
342
|
-
clarificationQuestion: 'Where should this data be stored?',
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
return assumptions;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Detect behavior assumptions
|
|
351
|
-
*/
|
|
352
|
-
function detectBehaviorAssumptions(description, acceptanceCriteria) {
|
|
353
|
-
const assumptions = [];
|
|
354
|
-
const text = `${description} ${acceptanceCriteria.join(' ')}`.toLowerCase();
|
|
355
|
-
|
|
356
|
-
// Loading state - use module-level patterns
|
|
357
|
-
if (ASYNC_PATTERN.test(text) && !LOADING_PATTERN.test(text)) {
|
|
358
|
-
assumptions.push({
|
|
359
|
-
text: 'Loading states will be handled',
|
|
360
|
-
category: ASSUMPTION_CATEGORIES.BEHAVIOR,
|
|
361
|
-
confidence: CONFIDENCE.MEDIUM,
|
|
362
|
-
source: 'loading_state',
|
|
363
|
-
clarificationQuestion: 'How should loading states be displayed?',
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Edge cases - use module-level pattern
|
|
368
|
-
if (!EDGE_CASE_PATTERN.test(text)) {
|
|
369
|
-
assumptions.push({
|
|
370
|
-
text: 'Edge cases will follow existing patterns',
|
|
371
|
-
category: ASSUMPTION_CATEGORIES.BEHAVIOR,
|
|
372
|
-
confidence: CONFIDENCE.LOW,
|
|
373
|
-
source: 'edge_cases',
|
|
374
|
-
clarificationQuestion: 'What edge cases should be handled explicitly?',
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
return assumptions;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* Deduplicate assumptions by text similarity
|
|
383
|
-
*/
|
|
384
|
-
function deduplicateAssumptions(assumptions) {
|
|
385
|
-
const seen = new Set();
|
|
386
|
-
return assumptions.filter(a => {
|
|
387
|
-
const key = `${a.category}:${a.text.toLowerCase()}`;
|
|
388
|
-
if (seen.has(key)) return false;
|
|
389
|
-
seen.add(key);
|
|
390
|
-
return true;
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
* Format assumptions for display in spec
|
|
396
|
-
* @param {Assumption[]} assumptions
|
|
397
|
-
* @returns {string} Markdown formatted assumptions
|
|
398
|
-
*/
|
|
399
|
-
function formatAssumptionsForSpec(assumptions) {
|
|
400
|
-
if (assumptions.length === 0) {
|
|
401
|
-
return '> No assumptions detected - requirements are well-defined.';
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
const sections = [];
|
|
405
|
-
|
|
406
|
-
// Group by category
|
|
407
|
-
const byCategory = {};
|
|
408
|
-
for (const a of assumptions) {
|
|
409
|
-
if (!byCategory[a.category]) byCategory[a.category] = [];
|
|
410
|
-
byCategory[a.category].push(a);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
for (const [category, items] of Object.entries(byCategory)) {
|
|
414
|
-
const categoryTitle = category.charAt(0).toUpperCase() + category.slice(1);
|
|
415
|
-
sections.push(`### ${categoryTitle}`);
|
|
416
|
-
|
|
417
|
-
for (const item of items) {
|
|
418
|
-
const confidenceBar = getConfidenceBar(item.confidence);
|
|
419
|
-
const needsFlag = item.needsClarification ? ' ⚠️' : '';
|
|
420
|
-
sections.push(`- **[${item.id}]** ${item.text} ${confidenceBar}${needsFlag}`);
|
|
421
|
-
if (item.needsClarification) {
|
|
422
|
-
sections.push(` - *Clarify:* ${item.clarificationQuestion}`);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
sections.push('');
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
return sections.join('\n');
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
/**
|
|
432
|
-
* Get confidence bar visualization
|
|
433
|
-
*/
|
|
434
|
-
function getConfidenceBar(confidence) {
|
|
435
|
-
const filled = Math.round(confidence * 5);
|
|
436
|
-
const empty = 5 - filled;
|
|
437
|
-
return `[${CONFIDENCE_FILLED.repeat(filled)}${CONFIDENCE_EMPTY.repeat(empty)}]`;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* Get assumptions that need clarification
|
|
442
|
-
* @param {Assumption[]} assumptions
|
|
443
|
-
* @returns {Assumption[]} Assumptions below threshold
|
|
444
|
-
*/
|
|
445
|
-
function getAssumptionsNeedingClarification(assumptions) {
|
|
446
|
-
return assumptions.filter(a => a.needsClarification);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* Generate clarification questions for AskUserQuestion tool
|
|
451
|
-
* @param {Assumption[]} assumptions - Assumptions needing clarification
|
|
452
|
-
* @returns {Object[]} Questions formatted for AskUserQuestion
|
|
453
|
-
*/
|
|
454
|
-
function generateClarificationQuestions(assumptions) {
|
|
455
|
-
const needClarification = getAssumptionsNeedingClarification(assumptions);
|
|
456
|
-
|
|
457
|
-
// Limit to 4 questions (AskUserQuestion limit)
|
|
458
|
-
const topQuestions = needClarification.slice(0, 4);
|
|
459
|
-
|
|
460
|
-
return topQuestions.map(a => ({
|
|
461
|
-
question: a.clarificationQuestion,
|
|
462
|
-
header: a.category.slice(0, 12),
|
|
463
|
-
options: [
|
|
464
|
-
{ label: 'Yes, correct', description: `Confirm: ${a.text}` },
|
|
465
|
-
{ label: 'No, clarify', description: 'I\'ll provide more details' },
|
|
466
|
-
{ label: 'Skip for now', description: 'Proceed with assumption' },
|
|
467
|
-
],
|
|
468
|
-
multiSelect: false,
|
|
469
|
-
assumption: a, // Include original assumption for reference
|
|
470
|
-
}));
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
module.exports = {
|
|
474
|
-
detectAssumptions,
|
|
475
|
-
formatAssumptionsForSpec,
|
|
476
|
-
getAssumptionsNeedingClarification,
|
|
477
|
-
generateClarificationQuestions,
|
|
478
|
-
ASSUMPTION_CATEGORIES,
|
|
479
|
-
CONFIDENCE,
|
|
480
|
-
CLARIFICATION_THRESHOLD,
|
|
481
|
-
};
|
|
1
|
+
// DEPRECATED: This file has been moved to scripts/flow-assumption-detector.js
|
|
2
|
+
// This copy is kept for backward compatibility with existing installations.
|
|
3
|
+
// It re-exports from the new location.
|
|
4
|
+
module.exports = require('../../scripts/flow-assumption-detector');
|