wogiflow 1.4.1 → 1.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.
- package/.claude/commands/wogi-init.md +0 -8
- package/.claude/commands/wogi-onboard.md +1 -9
- package/.claude/commands/wogi-research.md +14 -20
- package/.claude/commands/wogi-test-browser.md +4 -6
- package/.claude/docs/knowledge-base/02-task-execution/01-task-planning.md +1 -1
- package/.claude/docs/knowledge-base/02-task-execution/external-integrations.md +1 -1
- package/.claude/docs/knowledge-base/03-self-improvement/long-input-processing.md +1 -1
- package/.claude/docs/knowledge-base/configuration/all-options.md +1 -1
- package/.workflow/bridges/base-bridge.js +5 -5
- package/README.md +5 -26
- package/lib/installer.js +1 -1
- package/package.json +2 -3
- package/scripts/flow-bridge.js +7 -8
- package/scripts/flow-consistency-check.js +110 -9
- package/scripts/flow-hooks.js +1 -1
- package/scripts/flow-init +0 -2
- package/scripts/flow-review.js +7 -2
- package/scripts/flow-skill-matcher.js +2 -2
- package/scripts/flow-start.js +1 -1
- package/scripts/flow-utils.js +3 -9
- package/scripts/flow-verify.js +5 -2
- package/scripts/hooks/adapters/claude-code.js +1 -1
- package/scripts/hooks/core/constants.js +0 -6
- package/.claude/rules/README.md +0 -60
- package/.claude/rules/architecture/component-reuse.md +0 -38
- package/.claude/rules/architecture/document-structure.md +0 -76
- package/.claude/rules/architecture/feature-refactoring-cleanup.md +0 -87
- package/.claude/rules/architecture/model-management.md +0 -35
- package/.claude/rules/architecture/self-maintenance.md +0 -87
- package/.claude/rules/code-style/naming-conventions.md +0 -55
- package/.claude/rules/security/security-patterns.md +0 -176
- package/.claude/skills/figma-analyzer/knowledge/learnings.md +0 -11
- package/.workflow/agents/performance.md +0 -112
- package/.workflow/specs/architecture.md.template +0 -24
- package/.workflow/specs/stack.md.template +0 -33
- package/.workflow/specs/testing.md.template +0 -36
- package/.workflow/templates/agents-md.hbs +0 -127
- package/scripts/flow-operational-scanner.js +0 -762
- package/scripts/flow-quality-guard.js +0 -594
- package/scripts/hooks/core/long-input-gate.js +0 -293
|
@@ -764,14 +764,6 @@ if (webmcpFrameworks.some(f => normalizedFrontend.includes(f))) {
|
|
|
764
764
|
fallbackEnabled: true,
|
|
765
765
|
maxToolCalls: 20
|
|
766
766
|
};
|
|
767
|
-
config.browserTesting = {
|
|
768
|
-
enabled: true,
|
|
769
|
-
runOnTaskComplete: true,
|
|
770
|
-
runForUITasks: true,
|
|
771
|
-
flowsPath: ".workflow/tests/flows/",
|
|
772
|
-
stopOnFail: true,
|
|
773
|
-
timeout: 30000
|
|
774
|
-
};
|
|
775
767
|
}
|
|
776
768
|
```
|
|
777
769
|
|
|
@@ -123,7 +123,7 @@ Display:
|
|
|
123
123
|
After extraction, classify each pattern using its `lastSeen` date:
|
|
124
124
|
|
|
125
125
|
```javascript
|
|
126
|
-
// Configurable thresholds
|
|
126
|
+
// Configurable thresholds
|
|
127
127
|
const CURRENT_MONTHS = 6; // Default: patterns seen in last 6 months
|
|
128
128
|
const TRANSITIONAL_MONTHS = 18; // Default: patterns seen 6-18 months ago
|
|
129
129
|
// Anything older than TRANSITIONAL_MONTHS is "legacy"
|
|
@@ -589,14 +589,6 @@ Display:
|
|
|
589
589
|
fallbackEnabled: true,
|
|
590
590
|
maxToolCalls: 20
|
|
591
591
|
};
|
|
592
|
-
config.browserTesting = {
|
|
593
|
-
enabled: true,
|
|
594
|
-
runOnTaskComplete: true,
|
|
595
|
-
runForUITasks: true,
|
|
596
|
-
flowsPath: ".workflow/tests/flows/",
|
|
597
|
-
stopOnFail: true,
|
|
598
|
-
timeout: 30000
|
|
599
|
-
};
|
|
600
592
|
// Auto-generate initial WebMCP tool definitions
|
|
601
593
|
// Run: flow webmcp-generate scan
|
|
602
594
|
}
|
|
@@ -150,9 +150,9 @@ ACTION: ALWAYS web search "[tool] latest documentation [current year]"
|
|
|
150
150
|
Before answering, explicitly list:
|
|
151
151
|
```markdown
|
|
152
152
|
## My Assumptions
|
|
153
|
-
1. [VERIFY]
|
|
153
|
+
1. [VERIFY] Library X supports feature Y → Confidence: LOW (training data)
|
|
154
154
|
2. [OK] Project uses JavaScript → Confidence: HIGH (read package.json)
|
|
155
|
-
3. [VERIFY]
|
|
155
|
+
3. [VERIFY] Config format is correct → Confidence: LOW (haven't read docs)
|
|
156
156
|
```
|
|
157
157
|
|
|
158
158
|
Any assumption marked `[VERIFY]` with `LOW` confidence **MUST** be verified.
|
|
@@ -165,7 +165,7 @@ Every claim needs a traceable source:
|
|
|
165
165
|
| Claim | Source Type | Source Location | Confidence |
|
|
166
166
|
|-------|-------------|-----------------|------------|
|
|
167
167
|
| "Hooks are supported" | Live Docs | github.com/x/docs/hooks | HIGH |
|
|
168
|
-
| "Settings format is X" | File Read | .
|
|
168
|
+
| "Settings format is X" | File Read | .workflow/config.json | HIGH |
|
|
169
169
|
| "Feature Y exists" | Training Data | None | LOW - VERIFY |
|
|
170
170
|
```
|
|
171
171
|
|
|
@@ -218,32 +218,32 @@ In `.workflow/config.json`:
|
|
|
218
218
|
### Example 1: Capability Question
|
|
219
219
|
|
|
220
220
|
```
|
|
221
|
-
User: Does
|
|
221
|
+
User: Does Claude Code support custom hooks?
|
|
222
222
|
|
|
223
|
-
/wogi-research "Does
|
|
223
|
+
/wogi-research "Does Claude Code support custom hooks?"
|
|
224
224
|
```
|
|
225
225
|
|
|
226
226
|
Research output:
|
|
227
227
|
```
|
|
228
228
|
## Research Report
|
|
229
229
|
|
|
230
|
-
**Question:** Does
|
|
230
|
+
**Question:** Does Claude Code support custom hooks?
|
|
231
231
|
**Depth:** standard
|
|
232
232
|
**Confidence:** HIGH
|
|
233
233
|
|
|
234
234
|
### Conclusion
|
|
235
|
-
Yes,
|
|
235
|
+
Yes, Claude Code supports hooks since version 2.1.x.
|
|
236
236
|
|
|
237
237
|
### Evidence Chain
|
|
238
238
|
| Claim | Source | Confidence |
|
|
239
239
|
|-------|--------|------------|
|
|
240
|
-
| Hooks supported | https://
|
|
241
|
-
| Configuration in .
|
|
240
|
+
| Hooks supported | https://docs.anthropic.com/claude-code/hooks | HIGH |
|
|
241
|
+
| Configuration in .claude/settings.local.json | File read | HIGH |
|
|
242
242
|
|
|
243
243
|
### Searches Performed
|
|
244
|
-
1. Web: "
|
|
245
|
-
2. Local: .
|
|
246
|
-
3. Local: .
|
|
244
|
+
1. Web: "Claude Code hooks documentation 2026"
|
|
245
|
+
2. Local: .claude/settings.local.json
|
|
246
|
+
3. Local: .claude/**/*.md
|
|
247
247
|
```
|
|
248
248
|
|
|
249
249
|
### Example 2: Architecture Question
|
|
@@ -269,11 +269,5 @@ When `research.strictMode` is enabled and `research.autoTrigger` is true:
|
|
|
269
269
|
|
|
270
270
|
## CLI Compatibility
|
|
271
271
|
|
|
272
|
-
This command
|
|
273
|
-
|
|
274
|
-
- Gemini CLI
|
|
275
|
-
- Codex (OpenAI)
|
|
276
|
-
- OpenCode
|
|
277
|
-
- Cline/Cursor
|
|
278
|
-
|
|
279
|
-
State is stored in `.workflow/` for cross-CLI persistence.
|
|
272
|
+
This command currently supports Claude Code only.
|
|
273
|
+
State is stored in `.workflow/` for persistence across sessions.
|
|
@@ -309,13 +309,11 @@ Controlled by `.workflow/config.json`:
|
|
|
309
309
|
|
|
310
310
|
```json
|
|
311
311
|
{
|
|
312
|
-
"
|
|
312
|
+
"webmcp": {
|
|
313
313
|
"enabled": true,
|
|
314
|
-
"
|
|
315
|
-
"
|
|
316
|
-
"
|
|
317
|
-
"stopOnFail": true,
|
|
318
|
-
"timeout": 30000
|
|
314
|
+
"toolsPath": ".workflow/webmcp/tools.json",
|
|
315
|
+
"fallbackEnabled": true,
|
|
316
|
+
"maxToolCalls": 20
|
|
319
317
|
}
|
|
320
318
|
}
|
|
321
319
|
```
|
|
@@ -255,5 +255,5 @@ For complex tasks, analyze multiple implementation approaches before committing.
|
|
|
255
255
|
## Related
|
|
256
256
|
|
|
257
257
|
- [Execution Loop](./02-execution-loop.md) - How tasks are executed
|
|
258
|
-
- [Story Writer Agent](
|
|
258
|
+
- [Story Writer Agent](../../../../agents/story-writer.md) - Story creation guidelines
|
|
259
259
|
- [Configuration Reference](../configuration/all-options.md) - All config options
|
|
@@ -133,4 +133,4 @@ When importing, external tasks are mapped to WogiFlow tasks:
|
|
|
133
133
|
## Related
|
|
134
134
|
|
|
135
135
|
- [Task Planning](./01-task-planning.md) - How tasks are structured
|
|
136
|
-
- [
|
|
136
|
+
- [Future Features](../future-features.md) - Background sync (planned)
|
|
@@ -152,7 +152,7 @@ The system will recognize the old `transcriptDigestion` config key and warn abou
|
|
|
152
152
|
|
|
153
153
|
## Related
|
|
154
154
|
|
|
155
|
-
- [
|
|
155
|
+
- [Development Tools](../05-development-tools/README.md) - Available dev tools
|
|
156
156
|
- [Task Execution](../02-task-execution/02-execution-loop.md) - How tasks flow through gates
|
|
157
157
|
|
|
158
158
|
---
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Base Bridge Class
|
|
3
3
|
*
|
|
4
|
-
* Abstract base class for CLI bridges.
|
|
5
|
-
*
|
|
4
|
+
* Abstract base class for CLI bridges. Currently only Claude Code is supported.
|
|
5
|
+
* Generates CLI-specific file structure from the universal .workflow/ config.
|
|
6
6
|
*
|
|
7
7
|
* Architecture:
|
|
8
8
|
*
|
|
9
9
|
* .workflow/ ← Universal source of truth
|
|
10
10
|
* ├── config.json ← Contains cli.type setting
|
|
11
|
-
* ├── models/ ← Model registry
|
|
12
|
-
* ├── skills/ ← Skills
|
|
11
|
+
* ├── models/ ← Model registry
|
|
12
|
+
* ├── skills/ ← Skills
|
|
13
13
|
* └── templates/ ← Templates for generating CLI files
|
|
14
14
|
* │
|
|
15
15
|
* ▼ (bridge generates CLI-specific files)
|
|
16
|
-
* .claude/
|
|
16
|
+
* .claude/ ← Generated by claude-bridge
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
const fs = require('fs');
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# WogiFlow
|
|
2
2
|
|
|
3
|
-
A self-improving AI development workflow that learns from your feedback
|
|
3
|
+
A self-improving AI development workflow that learns from your feedback. Currently supports **Claude Code**.
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
@@ -15,35 +15,16 @@ npx flow onboard
|
|
|
15
15
|
npx flow bridge sync
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
## Supported
|
|
18
|
+
## Supported CLI
|
|
19
19
|
|
|
20
|
-
WogiFlow
|
|
20
|
+
WogiFlow currently supports **Claude Code** with hard enforcement via hooks.
|
|
21
21
|
|
|
22
22
|
| CLI | Enforcement | Rules File | Min Version | Guide |
|
|
23
23
|
|-----|-------------|------------|-------------|-------|
|
|
24
24
|
| **Claude Code** | Hard (hooks) | `CLAUDE.md` | **2.1.23+** | [Guide](.claude/docs/knowledge-base/01-setup-onboarding/) |
|
|
25
|
-
| **Gemini CLI** | Hard (hooks) | `GEMINI.md` | - | - |
|
|
26
|
-
| **Cursor** | Mixed | `.cursor/rules/wogiflow.mdc` | - | - |
|
|
27
|
-
| **OpenCode** | Hard (plugins) | `AGENTS.md` | - | - |
|
|
28
|
-
| **Codex** | Soft (rules) | `AGENTS.md` | - | - |
|
|
29
|
-
| **Kimi** | Soft (rules) | `AGENTS.md` | - | - |
|
|
30
25
|
|
|
31
26
|
> **Claude Code 2.1.23+ Recommended**: Includes critical fixes for per-user temp directory isolation (shared systems), async hook cancellation, and ripgrep timeout reporting. Earlier versions may experience silent search failures.
|
|
32
27
|
|
|
33
|
-
**Enforcement levels:**
|
|
34
|
-
- **Hard**: Blocks operations before execution (best protection)
|
|
35
|
-
- **Mixed**: Hard at prompt level, soft after
|
|
36
|
-
- **Soft**: Advisory only (rules in context, no blocking)
|
|
37
|
-
|
|
38
|
-
### Switching CLIs
|
|
39
|
-
|
|
40
|
-
Workflow state is stored in `.workflow/state/` - CLI-agnostic. You can:
|
|
41
|
-
1. Start a task in Claude Code
|
|
42
|
-
2. Continue it in Cursor
|
|
43
|
-
3. Finish it in Gemini CLI
|
|
44
|
-
|
|
45
|
-
Run `npx flow bridge sync` after switching to regenerate CLI-specific files.
|
|
46
|
-
|
|
47
28
|
---
|
|
48
29
|
|
|
49
30
|
## Core Features
|
|
@@ -177,8 +158,6 @@ flow verify all # Run all quality gates
|
|
|
177
158
|
└── rules/ # Project rules
|
|
178
159
|
|
|
179
160
|
CLAUDE.md # Claude Code instructions (generated)
|
|
180
|
-
GEMINI.md # Gemini CLI instructions (generated)
|
|
181
|
-
AGENTS.md # Codex/Kimi/OpenCode instructions (generated)
|
|
182
161
|
```
|
|
183
162
|
|
|
184
163
|
---
|
|
@@ -225,9 +204,9 @@ Detailed documentation is in the [Knowledge Base](.claude/docs/knowledge-base/RE
|
|
|
225
204
|
| [Safety & Guardrails](.claude/docs/knowledge-base/06-safety-guardrails/) | Damage control, checkpoints, security |
|
|
226
205
|
| [Configuration](.claude/docs/knowledge-base/configuration/) | All configuration options |
|
|
227
206
|
|
|
228
|
-
###
|
|
207
|
+
### Setup
|
|
229
208
|
|
|
230
|
-
|
|
209
|
+
Run `npx flow bridge sync` to generate `CLAUDE.md` from your workflow configuration. See the [Setup & Onboarding docs](.claude/docs/knowledge-base/01-setup-onboarding/) for detailed instructions.
|
|
231
210
|
|
|
232
211
|
---
|
|
233
212
|
|
package/lib/installer.js
CHANGED
|
@@ -358,7 +358,7 @@ function createCLIConfig(projectRoot, cliKey, config) {
|
|
|
358
358
|
}
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
-
// Generate the rules/instructions file (CLAUDE.md
|
|
361
|
+
// Generate the rules/instructions file (CLAUDE.md)
|
|
362
362
|
// First try to use the bridge for proper template rendering
|
|
363
363
|
try {
|
|
364
364
|
const bridgesPath = path.join(projectRoot, '.workflow', 'bridges');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wogiflow",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
4
4
|
"description": "AI-powered development workflow management system with multi-model support",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -37,8 +37,7 @@
|
|
|
37
37
|
"ai",
|
|
38
38
|
"development",
|
|
39
39
|
"claude",
|
|
40
|
-
"
|
|
41
|
-
"opencode",
|
|
40
|
+
"claude-code",
|
|
42
41
|
"mcp",
|
|
43
42
|
"multi-model",
|
|
44
43
|
"automation",
|
package/scripts/flow-bridge.js
CHANGED
|
@@ -92,17 +92,15 @@ function listBridges() {
|
|
|
92
92
|
function showStatus() {
|
|
93
93
|
const config = getConfig();
|
|
94
94
|
const cliType = config.cli?.type || 'claude-code';
|
|
95
|
-
const
|
|
95
|
+
const autoSyncConfig = config.cli?.autoSync || {};
|
|
96
96
|
|
|
97
97
|
console.log(`${colors.bold}CLI Bridge Status${colors.reset}`);
|
|
98
98
|
console.log('');
|
|
99
99
|
console.log(` CLI Type: ${colors.cyan}${cliType}${colors.reset}`);
|
|
100
|
-
console.log(` Auto Sync: ${
|
|
101
|
-
console.log(` Sync on
|
|
100
|
+
console.log(` Auto Sync: ${autoSyncConfig.enabled ? colors.green + 'enabled' : colors.yellow + 'disabled'}${colors.reset}`);
|
|
101
|
+
console.log(` Sync on Start: ${autoSyncConfig.onSessionStart ? colors.green + 'enabled' : colors.yellow + 'disabled'}${colors.reset}`);
|
|
102
102
|
console.log('');
|
|
103
103
|
|
|
104
|
-
// Check if bridge file exists
|
|
105
|
-
const bridgePath = path.join(BRIDGES_DIR, `${cliType.replace('-', '-')}-bridge.js`);
|
|
106
104
|
// Check bridge file (Claude Code only)
|
|
107
105
|
const bridgeFile = 'claude-bridge.js';
|
|
108
106
|
const bridgeExists = fs.existsSync(path.join(BRIDGES_DIR, bridgeFile));
|
|
@@ -136,9 +134,10 @@ async function syncBridge(options = {}) {
|
|
|
136
134
|
const verbose = options.verbose || process.argv.includes('--verbose') || process.argv.includes('-v');
|
|
137
135
|
const force = options.force || process.argv.includes('--force') || process.argv.includes('-f');
|
|
138
136
|
|
|
139
|
-
// Check for CLI type argument (e.g., "flow bridge sync
|
|
140
|
-
|
|
141
|
-
const
|
|
137
|
+
// Check for CLI type argument (e.g., "flow bridge sync claude-code")
|
|
138
|
+
// Skip flags (--force, -f, --verbose, -v) when looking for CLI type
|
|
139
|
+
const cliTypeArg = process.argv.slice(3).find(arg => !arg.startsWith('-'));
|
|
140
|
+
const requestedCliType = cliTypeArg ? normalizeCliType(cliTypeArg) : null;
|
|
142
141
|
|
|
143
142
|
if (cliTypeArg && !requestedCliType) {
|
|
144
143
|
console.error(`${colors.red}Error:${colors.reset} Unknown CLI type: ${cliTypeArg}`);
|
|
@@ -97,7 +97,13 @@ function isHeaderRow(name) {
|
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* Extract component entries from app-map.md
|
|
100
|
-
* Parses markdown tables and lists to find component references
|
|
100
|
+
* Parses markdown tables and lists to find component references.
|
|
101
|
+
*
|
|
102
|
+
* Supports multiple table formats:
|
|
103
|
+
* 2-col: | Name | path/to/file.tsx |
|
|
104
|
+
* 4-col: | Component | Variants | path/to/file.tsx | Details |
|
|
105
|
+
* (any column containing a file-like path is extracted)
|
|
106
|
+
*
|
|
101
107
|
* @returns {Object[]} Array of { name, path, type }
|
|
102
108
|
*/
|
|
103
109
|
function parseAppMap() {
|
|
@@ -106,19 +112,38 @@ function parseAppMap() {
|
|
|
106
112
|
|
|
107
113
|
const entries = [];
|
|
108
114
|
|
|
109
|
-
// Parse table rows:
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
// Parse table rows generically: extract the first column as name,
|
|
116
|
+
// then find a column containing a file path (with extension).
|
|
117
|
+
// This handles 2-col, 3-col, and 4-col tables.
|
|
118
|
+
const lines = content.split('\n');
|
|
119
|
+
for (const line of lines) {
|
|
120
|
+
// Must be a table row
|
|
121
|
+
if (!line.includes('|')) continue;
|
|
122
|
+
const cells = line.split('|').map(c => c.trim()).filter(c => c.length > 0);
|
|
123
|
+
if (cells.length < 2) continue;
|
|
124
|
+
|
|
125
|
+
const name = cells[0].replace(/`/g, '').trim();
|
|
115
126
|
if (isHeaderRow(name)) continue;
|
|
127
|
+
// Skip separator rows
|
|
128
|
+
if (/^[-:]+$/.test(name)) continue;
|
|
129
|
+
// Skip italic placeholder rows
|
|
130
|
+
if (name.startsWith('_') && name.endsWith('_')) continue;
|
|
131
|
+
|
|
132
|
+
// Find a cell that looks like a file path (contains a dot-extension)
|
|
133
|
+
const pathCell = cells.find((c, i) => i > 0 && /[a-zA-Z0-9_/-]+\.[a-z]{1,5}/.test(c));
|
|
134
|
+
if (!pathCell) continue;
|
|
135
|
+
// Extract the path, stripping backticks, markdown links, etc.
|
|
136
|
+
const fileMatch = pathCell.match(/`?([^`\s()\[\]]+\.[a-z]{1,5})`?/);
|
|
137
|
+
if (!fileMatch) continue;
|
|
138
|
+
const filePath = fileMatch[1].trim();
|
|
139
|
+
|
|
116
140
|
entries.push({ name, path: filePath, type: 'component', source: 'app-map' });
|
|
117
141
|
}
|
|
118
142
|
|
|
119
143
|
// Parse list entries: - **ComponentName** (`path/to/file.tsx`)
|
|
120
144
|
// Requires bold marker (**Name**) immediately after bullet to avoid matching prose lines
|
|
121
145
|
const listPattern = /^[-*]\s+\*\*([^*]+)\*\*\s*\(?`([^`]+\.[a-z]+)`\)?/gim;
|
|
146
|
+
let match;
|
|
122
147
|
while ((match = listPattern.exec(content)) !== null) {
|
|
123
148
|
const name = match[1].trim();
|
|
124
149
|
const filePath = match[2].trim();
|
|
@@ -130,6 +155,11 @@ function parseAppMap() {
|
|
|
130
155
|
|
|
131
156
|
/**
|
|
132
157
|
* Extract function entries from function-map.md
|
|
158
|
+
*
|
|
159
|
+
* Supports two formats:
|
|
160
|
+
* Table: | functionName | path/to/file.js | description |
|
|
161
|
+
* Heading: ### functionName / **File**: path/to/file.js
|
|
162
|
+
*
|
|
133
163
|
* @returns {Object[]} Array of { name, path, type }
|
|
134
164
|
*/
|
|
135
165
|
function parseFunctionMap() {
|
|
@@ -138,7 +168,7 @@ function parseFunctionMap() {
|
|
|
138
168
|
|
|
139
169
|
const entries = [];
|
|
140
170
|
|
|
141
|
-
//
|
|
171
|
+
// Format 1: Table rows: | functionName | path/to/file.js | description |
|
|
142
172
|
const tablePattern = /\|\s*`?([^|`]+?)`?\s*\|\s*`?([^|`]+\.[a-z]+)`?\s*\|/gi;
|
|
143
173
|
let match;
|
|
144
174
|
while ((match = tablePattern.exec(content)) !== null) {
|
|
@@ -148,11 +178,46 @@ function parseFunctionMap() {
|
|
|
148
178
|
entries.push({ name, path: filePath, type: 'function', source: 'function-map' });
|
|
149
179
|
}
|
|
150
180
|
|
|
181
|
+
// Format 2: Heading + **File** metadata (actual format used by function-map.md)
|
|
182
|
+
// ### functionName
|
|
183
|
+
// **File**: path/to/file.js
|
|
184
|
+
const lines = content.split('\n');
|
|
185
|
+
let inCodeBlock = false;
|
|
186
|
+
for (let i = 0; i < lines.length; i++) {
|
|
187
|
+
// Skip fenced code blocks
|
|
188
|
+
if (lines[i].trimStart().startsWith('```')) {
|
|
189
|
+
inCodeBlock = !inCodeBlock;
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (inCodeBlock) continue;
|
|
193
|
+
|
|
194
|
+
const headingMatch = lines[i].match(/^###\s+(\w+)/);
|
|
195
|
+
if (!headingMatch) continue;
|
|
196
|
+
const name = headingMatch[1];
|
|
197
|
+
// Look for **File**: in the next few lines
|
|
198
|
+
for (let j = i + 1; j < Math.min(i + 5, lines.length); j++) {
|
|
199
|
+
if (lines[j].trimStart().startsWith('```')) break;
|
|
200
|
+
const fileMatch = lines[j].match(/\*\*File\*\*:\s*(.+)/);
|
|
201
|
+
if (fileMatch) {
|
|
202
|
+
const filePath = fileMatch[1].trim();
|
|
203
|
+
entries.push({ name, path: filePath, type: 'function', source: 'function-map' });
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
// Stop if we hit another heading
|
|
207
|
+
if (lines[j].startsWith('###')) break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
151
211
|
return entries;
|
|
152
212
|
}
|
|
153
213
|
|
|
154
214
|
/**
|
|
155
215
|
* Extract API endpoint entries from api-map.md
|
|
216
|
+
*
|
|
217
|
+
* Supports two formats:
|
|
218
|
+
* Table: | GET | /api/users | path/to/handler.ts | description |
|
|
219
|
+
* Heading: ### GET /api/users / **File**: path/to/handler.ts
|
|
220
|
+
*
|
|
156
221
|
* @returns {Object[]} Array of { name, path, type, method, endpoint }
|
|
157
222
|
*/
|
|
158
223
|
function parseApiMap() {
|
|
@@ -161,7 +226,7 @@ function parseApiMap() {
|
|
|
161
226
|
|
|
162
227
|
const entries = [];
|
|
163
228
|
|
|
164
|
-
//
|
|
229
|
+
// Format 1: Table rows: | GET | /api/users | path/to/handler.ts | description |
|
|
165
230
|
const tablePattern = /\|\s*(GET|POST|PUT|PATCH|DELETE)\s*\|\s*([^|]+?)\s*\|\s*`?([^|`]+\.[a-z]+)`?\s*\|/gi;
|
|
166
231
|
let match;
|
|
167
232
|
while ((match = tablePattern.exec(content)) !== null) {
|
|
@@ -179,6 +244,42 @@ function parseApiMap() {
|
|
|
179
244
|
});
|
|
180
245
|
}
|
|
181
246
|
|
|
247
|
+
// Format 2: Heading + **File** metadata (actual format used by api-map.md)
|
|
248
|
+
// ### GET /api/users
|
|
249
|
+
// **File**: path/to/handler.ts
|
|
250
|
+
const lines = content.split('\n');
|
|
251
|
+
let inCodeBlock = false;
|
|
252
|
+
for (let i = 0; i < lines.length; i++) {
|
|
253
|
+
if (lines[i].trimStart().startsWith('```')) {
|
|
254
|
+
inCodeBlock = !inCodeBlock;
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
if (inCodeBlock) continue;
|
|
258
|
+
|
|
259
|
+
const headingMatch = lines[i].match(/^###\s+(GET|POST|PUT|PATCH|DELETE)\s+(\S+)/i);
|
|
260
|
+
if (!headingMatch) continue;
|
|
261
|
+
const method = headingMatch[1].toUpperCase();
|
|
262
|
+
const endpoint = headingMatch[2];
|
|
263
|
+
// Look for **File**: in the next few lines
|
|
264
|
+
for (let j = i + 1; j < Math.min(i + 5, lines.length); j++) {
|
|
265
|
+
if (lines[j].trimStart().startsWith('```')) break;
|
|
266
|
+
const fileMatch = lines[j].match(/\*\*File\*\*:\s*(.+)/);
|
|
267
|
+
if (fileMatch) {
|
|
268
|
+
const filePath = fileMatch[1].trim();
|
|
269
|
+
entries.push({
|
|
270
|
+
name: `${method} ${endpoint}`,
|
|
271
|
+
path: filePath,
|
|
272
|
+
type: 'api',
|
|
273
|
+
method,
|
|
274
|
+
endpoint,
|
|
275
|
+
source: 'api-map'
|
|
276
|
+
});
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
if (lines[j].startsWith('###')) break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
182
283
|
return entries;
|
|
183
284
|
}
|
|
184
285
|
|
package/scripts/flow-hooks.js
CHANGED
|
@@ -447,7 +447,7 @@ function showHelp() {
|
|
|
447
447
|
console.log(`
|
|
448
448
|
Wogi Flow - CLI Hooks Manager
|
|
449
449
|
|
|
450
|
-
Manage hooks for
|
|
450
|
+
Manage hooks for Claude Code CLI
|
|
451
451
|
|
|
452
452
|
Usage:
|
|
453
453
|
flow hooks setup Install hooks for configured targets
|
package/scripts/flow-init
CHANGED
|
@@ -36,8 +36,6 @@ echo -e "${CYAN}║${NC}
|
|
|
36
36
|
echo -e "${CYAN}║${NC} ${YELLOW}Start your AI assistant:${NC} ${CYAN}║${NC}"
|
|
37
37
|
echo -e "${CYAN}║${NC} ${CYAN}║${NC}"
|
|
38
38
|
echo -e "${CYAN}║${NC} ${GREEN}claude${NC} (Claude Code) ${CYAN}║${NC}"
|
|
39
|
-
echo -e "${CYAN}║${NC} ${GREEN}gemini${NC} (Gemini CLI) ${CYAN}║${NC}"
|
|
40
|
-
echo -e "${CYAN}║${NC} ${GREEN}opencode${NC} (OpenCode) ${CYAN}║${NC}"
|
|
41
39
|
echo -e "${CYAN}║${NC} ${CYAN}║${NC}"
|
|
42
40
|
echo -e "${CYAN}║${NC} Then say: ${YELLOW}\"setup wogiflow\"${NC} or run ${YELLOW}/wogi-init${NC} ${CYAN}║${NC}"
|
|
43
41
|
echo -e "${CYAN}║${NC} ${CYAN}║${NC}"
|
package/scripts/flow-review.js
CHANGED
|
@@ -427,8 +427,9 @@ Configure in config.json under review.autoMultiPass.
|
|
|
427
427
|
const specFirstGating = config.review?.specFirstGating !== false;
|
|
428
428
|
|
|
429
429
|
// Run verification gates
|
|
430
|
+
let gateResults = null;
|
|
430
431
|
if (!skipVerify) {
|
|
431
|
-
|
|
432
|
+
gateResults = runVerificationGates(changedFiles, { taskId });
|
|
432
433
|
console.log(formatGateResults(gateResults));
|
|
433
434
|
console.log('');
|
|
434
435
|
|
|
@@ -456,8 +457,12 @@ Configure in config.json under review.autoMultiPass.
|
|
|
456
457
|
}
|
|
457
458
|
}
|
|
458
459
|
|
|
459
|
-
// If verify-only, stop here
|
|
460
|
+
// If verify-only, stop here with appropriate exit code
|
|
460
461
|
if (verifyOnly) {
|
|
462
|
+
if (gateResults && !gateResults.allPassed) {
|
|
463
|
+
console.log(color('yellow', '⚠ Verification complete with failures.'));
|
|
464
|
+
process.exit(1);
|
|
465
|
+
}
|
|
461
466
|
console.log(color('green', '✓ Verification complete.'));
|
|
462
467
|
process.exit(0);
|
|
463
468
|
}
|
|
@@ -128,8 +128,8 @@ const DEFAULT_TRIGGERS = {
|
|
|
128
128
|
taskTypes: ['feature'],
|
|
129
129
|
categories: ['design', 'ui']
|
|
130
130
|
}
|
|
131
|
-
// Note: transcript/long-input processing is
|
|
132
|
-
// not as a skill. See
|
|
131
|
+
// Note: transcript/long-input processing is handled by the longInputGate config,
|
|
132
|
+
// not as a skill. See config.longInputGate in .workflow/config.json
|
|
133
133
|
};
|
|
134
134
|
|
|
135
135
|
// ============================================================
|
package/scripts/flow-start.js
CHANGED
|
@@ -658,7 +658,7 @@ async function main() {
|
|
|
658
658
|
}
|
|
659
659
|
|
|
660
660
|
// v3.1: Hierarchical context from summary tree (recursive enhancements)
|
|
661
|
-
if (contextCompact && config.
|
|
661
|
+
if (contextCompact && config.context?.compaction?.enabled !== false) {
|
|
662
662
|
try {
|
|
663
663
|
const treeStats = contextCompact.getStats();
|
|
664
664
|
if (treeStats.exists) {
|
package/scripts/flow-utils.js
CHANGED
|
@@ -58,21 +58,17 @@ const MAX_SESSION_HISTORY = 50;
|
|
|
58
58
|
const MAX_WORKFLOW_ITERATIONS = 100;
|
|
59
59
|
|
|
60
60
|
// ============================================================
|
|
61
|
-
// CLI Session ID Detection
|
|
61
|
+
// CLI Session ID Detection
|
|
62
62
|
// ============================================================
|
|
63
63
|
|
|
64
64
|
/**
|
|
65
65
|
* Get the current AI CLI session ID.
|
|
66
|
-
*
|
|
67
|
-
* Returns null if no session ID is available.
|
|
66
|
+
* Currently supports Claude Code only.
|
|
68
67
|
*
|
|
69
68
|
* @returns {string|null} Session ID or null
|
|
70
69
|
*/
|
|
71
70
|
function getSessionId() {
|
|
72
|
-
return process.env.CLAUDE_SESSION_ID
|
|
73
|
-
|| process.env.GEMINI_SESSION_ID // Gemini CLI (future)
|
|
74
|
-
|| process.env.CODEX_SESSION_ID // Codex CLI (future)
|
|
75
|
-
|| process.env.OPENCODE_SESSION_ID // OpenCode (future)
|
|
71
|
+
return process.env.CLAUDE_SESSION_ID
|
|
76
72
|
|| process.env.AI_SESSION_ID // Generic fallback
|
|
77
73
|
|| null;
|
|
78
74
|
}
|
|
@@ -132,14 +128,12 @@ const WORKFLOW_DIR = path.join(PROJECT_ROOT, '.workflow');
|
|
|
132
128
|
const STATE_DIR = path.join(WORKFLOW_DIR, 'state');
|
|
133
129
|
|
|
134
130
|
const CLAUDE_DIR = path.join(PROJECT_ROOT, '.claude');
|
|
135
|
-
const GEMINI_DIR = path.join(PROJECT_ROOT, '.gemini');
|
|
136
131
|
|
|
137
132
|
const PATHS = {
|
|
138
133
|
root: PROJECT_ROOT,
|
|
139
134
|
workflow: WORKFLOW_DIR,
|
|
140
135
|
state: STATE_DIR,
|
|
141
136
|
claude: CLAUDE_DIR,
|
|
142
|
-
gemini: GEMINI_DIR,
|
|
143
137
|
config: path.join(WORKFLOW_DIR, 'config.json'),
|
|
144
138
|
ready: path.join(STATE_DIR, 'ready.json'),
|
|
145
139
|
requestLog: path.join(STATE_DIR, 'request-log.md'),
|
package/scripts/flow-verify.js
CHANGED
|
@@ -35,6 +35,7 @@ class GateResult {
|
|
|
35
35
|
constructor(name) {
|
|
36
36
|
this.name = name;
|
|
37
37
|
this.passed = false;
|
|
38
|
+
this.skipped = false;
|
|
38
39
|
this.exitCode = null;
|
|
39
40
|
this.duration = 0;
|
|
40
41
|
this.stdout = '';
|
|
@@ -50,6 +51,7 @@ class GateResult {
|
|
|
50
51
|
return {
|
|
51
52
|
name: this.name,
|
|
52
53
|
passed: this.passed,
|
|
54
|
+
skipped: this.skipped,
|
|
53
55
|
exitCode: this.exitCode,
|
|
54
56
|
duration: this.duration,
|
|
55
57
|
command: this.command,
|
|
@@ -881,8 +883,9 @@ async function runGate(gateName, options = {}) {
|
|
|
881
883
|
const cmdConfig = detectCommand(gateConfig);
|
|
882
884
|
|
|
883
885
|
if (!cmdConfig) {
|
|
884
|
-
result.passed =
|
|
885
|
-
result.
|
|
886
|
+
result.passed = false;
|
|
887
|
+
result.skipped = true;
|
|
888
|
+
result.warnings = [{ message: `No tool detected for ${gateName}, skipping (treated as not passed)` }];
|
|
886
889
|
return result;
|
|
887
890
|
}
|
|
888
891
|
|
|
@@ -243,7 +243,7 @@ class ClaudeCodeAdapter extends BaseAdapter {
|
|
|
243
243
|
*/
|
|
244
244
|
transformPostToolUse(coreResult) {
|
|
245
245
|
// If validation was skipped or passed
|
|
246
|
-
if (coreResult.
|
|
246
|
+
if (coreResult.passed) {
|
|
247
247
|
const message = coreResult.summary || (coreResult.passed ? 'Validation passed' : null);
|
|
248
248
|
return {
|
|
249
249
|
continue: true,
|