wogiflow 2.4.2 → 2.4.4
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-start.md +124 -0
- package/.claude/docs/claude-code-compatibility.md +51 -0
- package/.claude/docs/explore-agents.md +11 -0
- package/.claude/settings.json +12 -1
- package/.workflow/models/registry.json +1 -1
- package/bin/flow +11 -1
- package/lib/workspace-contracts.js +599 -0
- package/lib/workspace-intelligence.js +600 -0
- package/lib/workspace-messages.js +441 -0
- package/lib/workspace-routing.js +485 -0
- package/lib/workspace-sync.js +339 -0
- package/lib/workspace.js +1073 -0
- package/package.json +4 -4
- package/scripts/MEMORY-ARCHITECTURE.md +1 -1
- package/scripts/base-workflow-step.js +136 -0
- package/scripts/flow-adaptive-learning.js +8 -9
- package/scripts/flow-aggregate.js +11 -6
- package/scripts/flow-api-index.js +4 -6
- package/scripts/flow-assumption-detector.js +0 -2
- package/scripts/flow-audit.js +15 -2
- package/scripts/flow-auto-context.js +8 -12
- package/scripts/flow-auto-learn.js +49 -49
- package/scripts/flow-background.js +5 -6
- package/scripts/flow-bridge-state.js +8 -10
- package/scripts/flow-bulk-loop.js +1 -3
- package/scripts/flow-bulk-orchestrator.js +1 -3
- package/scripts/flow-cascade-completion.js +0 -2
- package/scripts/flow-cascade.js +4 -4
- package/scripts/flow-checkpoint.js +10 -13
- package/scripts/flow-code-intelligence.js +10 -12
- package/scripts/flow-community-sync.js +4 -4
- package/scripts/flow-community.js +12 -20
- package/scripts/flow-config-defaults.js +28 -2
- package/scripts/flow-config-interactive.js +9 -5
- package/scripts/flow-config-loader.js +49 -92
- package/scripts/flow-config-substitution.js +0 -2
- package/scripts/flow-context-estimator.js +4 -4
- package/scripts/flow-context-init.js +10 -12
- package/scripts/flow-context-manager.js +0 -2
- package/scripts/flow-context-scoring.js +2 -2
- package/scripts/flow-contract-scan.js +6 -9
- package/scripts/flow-correct.js +29 -27
- package/scripts/flow-correction-detector.js +5 -1
- package/scripts/flow-damage-control.js +47 -54
- package/scripts/flow-decisions-merge.js +4 -14
- package/scripts/flow-diff.js +5 -8
- package/scripts/flow-done-gates.js +786 -0
- package/scripts/flow-done-report.js +123 -0
- package/scripts/flow-done.js +71 -717
- package/scripts/flow-entropy-monitor.js +1 -3
- package/scripts/flow-eval-calibration.js +257 -0
- package/scripts/flow-eval-judge.js +10 -1
- package/scripts/flow-eval.js +14 -5
- package/scripts/flow-extraction-review.js +1 -0
- package/scripts/flow-failure-categories.js +0 -2
- package/scripts/flow-figma-confirm.js +5 -9
- package/scripts/flow-figma-generate.js +8 -10
- package/scripts/flow-figma-index.js +8 -10
- package/scripts/flow-figma-match.js +3 -5
- package/scripts/flow-figma-mcp-server.js +2 -4
- package/scripts/flow-figma-orchestrator.js +2 -3
- package/scripts/flow-figma-registry.js +2 -3
- package/scripts/flow-framework-resolver.js +0 -2
- package/scripts/flow-function-index.js +4 -6
- package/scripts/flow-gate-confidence.js +2 -2
- package/scripts/flow-gitignore.js +0 -2
- package/scripts/flow-guided-edit.js +5 -6
- package/scripts/flow-health.js +5 -6
- package/scripts/flow-hook-errors.js +6 -0
- package/scripts/flow-hook-status.js +263 -0
- package/scripts/flow-hooks.js +17 -29
- package/scripts/flow-http-client.js +9 -8
- package/scripts/flow-hybrid-interactive.js +7 -12
- package/scripts/flow-hybrid-test.js +12 -13
- package/scripts/flow-instruction-richness.js +1 -1
- package/scripts/flow-io.js +21 -4
- package/scripts/flow-knowledge-router.js +9 -3
- package/scripts/flow-learning-orchestrator.js +318 -13
- package/scripts/flow-links.js +5 -7
- package/scripts/flow-long-input-association.js +275 -0
- package/scripts/flow-long-input-chunking.js +1 -0
- package/scripts/flow-long-input-cli.js +0 -2
- package/scripts/flow-long-input-complexity.js +0 -2
- package/scripts/flow-long-input-constants.js +0 -2
- package/scripts/flow-long-input-contradictions.js +351 -0
- package/scripts/flow-long-input-detection.js +0 -2
- package/scripts/flow-long-input-passes.js +885 -0
- package/scripts/flow-long-input-stories.js +1 -1
- package/scripts/flow-long-input-voice.js +0 -2
- package/scripts/flow-long-input.js +425 -3005
- package/scripts/flow-loop-retry-learning.js +2 -3
- package/scripts/flow-lsp.js +3 -3
- package/scripts/flow-mcp-docs.js +3 -4
- package/scripts/flow-memory-db.js +6 -8
- package/scripts/flow-memory-sync.js +18 -11
- package/scripts/flow-metrics.js +1 -2
- package/scripts/flow-model-adapter.js +2 -3
- package/scripts/flow-model-config.js +72 -104
- package/scripts/flow-model-router.js +2 -2
- package/scripts/flow-model-types.js +0 -2
- package/scripts/flow-multi-approach.js +5 -6
- package/scripts/flow-orchestrate-context.js +3 -7
- package/scripts/flow-orchestrate-rollback.js +3 -8
- package/scripts/flow-orchestrate-state.js +8 -14
- package/scripts/flow-orchestrate-templates.js +2 -6
- package/scripts/flow-orchestrate-validator.js +5 -9
- package/scripts/flow-orchestrate.js +126 -103
- package/scripts/flow-output.js +0 -2
- package/scripts/flow-parallel.js +1 -1
- package/scripts/flow-paths.js +23 -2
- package/scripts/flow-pattern-enforcer.js +30 -28
- package/scripts/flow-pattern-extractor.js +3 -4
- package/scripts/flow-pending.js +0 -2
- package/scripts/flow-permissions.js +2 -3
- package/scripts/flow-plugin-registry.js +10 -12
- package/scripts/flow-prd-manager.js +1 -1
- package/scripts/flow-progress.js +7 -9
- package/scripts/flow-prompt-composer.js +3 -3
- package/scripts/flow-prompt-template.js +2 -2
- package/scripts/flow-providers.js +7 -4
- package/scripts/flow-registry-manager.js +7 -12
- package/scripts/flow-regression.js +9 -11
- package/scripts/flow-roadmap.js +2 -2
- package/scripts/flow-run-trace.js +16 -15
- package/scripts/flow-safety.js +2 -5
- package/scripts/flow-scanner-base.js +5 -7
- package/scripts/flow-scenario-engine.js +1 -5
- package/scripts/flow-security.js +29 -0
- package/scripts/flow-session-end.js +32 -41
- package/scripts/flow-session-learning.js +53 -49
- package/scripts/flow-setup-hooks.js +2 -3
- package/scripts/flow-skill-create.js +7 -12
- package/scripts/flow-skill-generator.js +12 -16
- package/scripts/flow-skill-learn.js +17 -8
- package/scripts/flow-skill-matcher.js +1 -2
- package/scripts/flow-spec-generator.js +2 -4
- package/scripts/flow-stack-wizard.js +5 -7
- package/scripts/flow-standards-learner.js +35 -16
- package/scripts/flow-start.js +2 -0
- package/scripts/flow-stats-collector.js +2 -2
- package/scripts/flow-status.js +10 -10
- package/scripts/flow-statusline-setup.js +2 -2
- package/scripts/flow-step-changelog.js +2 -3
- package/scripts/flow-step-comments.js +66 -81
- package/scripts/flow-step-complexity.js +50 -70
- package/scripts/flow-step-coverage.js +3 -5
- package/scripts/flow-step-knowledge.js +2 -3
- package/scripts/flow-step-pr-tests.js +64 -74
- package/scripts/flow-step-regression.js +3 -5
- package/scripts/flow-step-review.js +86 -103
- package/scripts/flow-step-security.js +111 -121
- package/scripts/flow-step-silent-failures.js +56 -83
- package/scripts/flow-step-simplifier.js +52 -70
- package/scripts/flow-story.js +4 -7
- package/scripts/flow-strict-adherence.js +3 -4
- package/scripts/flow-task-checkpoint.js +36 -5
- package/scripts/flow-task-enforcer.js +2 -24
- package/scripts/flow-tech-debt.js +1 -1
- package/scripts/flow-template-extractor.js +1 -0
- package/scripts/flow-templates.js +11 -13
- package/scripts/flow-test-api.js +9 -13
- package/scripts/flow-test-discovery.js +1 -1
- package/scripts/flow-test-generate.js +5 -9
- package/scripts/flow-test-integrity.js +3 -7
- package/scripts/flow-test-ui.js +5 -9
- package/scripts/flow-testing-deps.js +1 -3
- package/scripts/flow-tiered-learning.js +4 -4
- package/scripts/flow-todowrite-sync.js +1 -1
- package/scripts/flow-tokens.js +0 -2
- package/scripts/flow-verification-profile.js +6 -10
- package/scripts/flow-verify.js +12 -16
- package/scripts/flow-version-check.js +4 -12
- package/scripts/flow-webmcp-generator.js +3 -5
- package/scripts/flow-workflow-steps.js +0 -2
- package/scripts/flow-workflow.js +9 -11
- package/scripts/hooks/adapters/claude-code.js +31 -0
- package/scripts/hooks/core/config-change.js +1 -0
- package/scripts/hooks/core/extension-registry.js +0 -2
- package/scripts/hooks/core/instructions-loaded.js +1 -1
- package/scripts/hooks/core/observation-capture.js +5 -5
- package/scripts/hooks/core/phase-gate.js +5 -0
- package/scripts/hooks/core/post-compact.js +1 -12
- package/scripts/hooks/core/research-gate.js +2 -12
- package/scripts/hooks/core/routing-gate.js +6 -0
- package/scripts/hooks/core/task-completed.js +12 -0
- package/scripts/hooks/core/task-created.js +83 -0
- package/scripts/hooks/core/worktree-lifecycle.js +1 -1
- package/scripts/hooks/entry/claude-code/config-change.js +6 -29
- package/scripts/hooks/entry/claude-code/instructions-loaded.js +5 -30
- package/scripts/hooks/entry/claude-code/post-compact.js +4 -31
- package/scripts/hooks/entry/claude-code/post-tool-use.js +121 -172
- package/scripts/hooks/entry/claude-code/pre-tool-use.js +260 -361
- package/scripts/hooks/entry/claude-code/session-end.js +4 -28
- package/scripts/hooks/entry/claude-code/session-start.js +205 -243
- package/scripts/hooks/entry/claude-code/setup.js +8 -49
- package/scripts/hooks/entry/claude-code/stop.js +40 -72
- package/scripts/hooks/entry/claude-code/task-completed.js +4 -28
- package/scripts/hooks/entry/claude-code/task-created.js +15 -0
- package/scripts/hooks/entry/claude-code/user-prompt-submit.js +113 -195
- package/scripts/hooks/entry/claude-code/worktree-create.js +6 -25
- package/scripts/hooks/entry/claude-code/worktree-remove.js +6 -25
- package/scripts/hooks/entry/shared/hook-runner.js +99 -0
- package/scripts/hooks/entry/shared/read-stdin.js +0 -2
- package/scripts/postinstall.js +2 -0
- package/scripts/registries/api-registry.js +0 -2
- package/scripts/registries/component-registry.js +5 -9
- package/scripts/registries/contract-scanner.js +2 -9
- package/scripts/registries/function-registry.js +0 -2
- package/scripts/registries/schema-registry.js +14 -18
- package/scripts/registries/service-registry.js +23 -27
|
@@ -8,32 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
const { handleSessionEnd } = require('../../core/session-end');
|
|
11
|
-
const {
|
|
12
|
-
const { readHookInput } = require('../shared/read-stdin');
|
|
11
|
+
const { runHook } = require('../shared/hook-runner');
|
|
13
12
|
|
|
14
|
-
async
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const input = parsedStdin || {};
|
|
18
|
-
const parsedInput = claudeCodeAdapter.parseInput(input);
|
|
19
|
-
|
|
20
|
-
// Handle session end
|
|
21
|
-
const coreResult = handleSessionEnd(parsedInput);
|
|
22
|
-
|
|
23
|
-
// Transform to Claude Code format
|
|
24
|
-
const output = claudeCodeAdapter.transformResult('SessionEnd', coreResult);
|
|
25
|
-
|
|
26
|
-
// Output JSON
|
|
27
|
-
console.log(JSON.stringify(output));
|
|
28
|
-
process.exit(0);
|
|
29
|
-
} catch (err) {
|
|
30
|
-
// Non-blocking error
|
|
31
|
-
console.error(`[Wogi Flow Hook Error] ${err.message}`);
|
|
32
|
-
console.log(JSON.stringify({ continue: true }));
|
|
33
|
-
process.exit(0);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Handle stdin properly
|
|
38
|
-
process.stdin.setEncoding('utf8');
|
|
39
|
-
main();
|
|
13
|
+
runHook('SessionEnd', async ({ parsedInput }) => {
|
|
14
|
+
return handleSessionEnd(parsedInput);
|
|
15
|
+
}, { failMode: 'silent' });
|
|
@@ -8,12 +8,11 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
const { gatherSessionContext } = require('../../core/session-context');
|
|
11
|
-
const { claudeCodeAdapter } = require('../../adapters/claude-code');
|
|
12
11
|
const { setCliSessionId, clearStaleCurrentTaskAsync } = require('../../../flow-session-state');
|
|
13
12
|
const { checkAndResetStalePhase } = require('../../core/phase-gate');
|
|
14
13
|
const { setRoutingPending } = require('../../core/routing-gate');
|
|
15
14
|
const { getConfig } = require('../../../flow-utils');
|
|
16
|
-
const {
|
|
15
|
+
const { runHook } = require('../shared/hook-runner');
|
|
17
16
|
|
|
18
17
|
// Lazy-load bridge state to avoid circular dependencies
|
|
19
18
|
let autoSyncBridge = null;
|
|
@@ -28,294 +27,257 @@ function getAutoSyncBridge() {
|
|
|
28
27
|
return autoSyncBridge;
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
async
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const bridgeSyncPromise = (async () => {
|
|
35
|
-
try {
|
|
36
|
-
const syncFn = getAutoSyncBridge();
|
|
37
|
-
await syncFn('claude-code', { silent: true });
|
|
38
|
-
} catch (err) {
|
|
39
|
-
if (process.env.DEBUG) {
|
|
40
|
-
console.error(`[session-start] Bridge auto-sync failed: ${err.message}`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
})();
|
|
44
|
-
|
|
45
|
-
// Read input from stdin (runs concurrently with bridge sync)
|
|
46
|
-
const { input: parsedStdin } = await readHookInput();
|
|
47
|
-
const input = parsedStdin || {};
|
|
48
|
-
const parsedInput = claudeCodeAdapter.parseInput(input);
|
|
49
|
-
|
|
50
|
-
// Wait for bridge sync to complete before proceeding
|
|
51
|
-
await bridgeSyncPromise;
|
|
52
|
-
|
|
53
|
-
// CLAUDE.md drift detection — check if manually edited since last sync
|
|
54
|
-
let driftDetected = false;
|
|
55
|
-
let driftMarkerMissing = false;
|
|
56
|
-
try {
|
|
57
|
-
const { checkClaudeMdDrift } = require('../../../flow-bridge-state');
|
|
58
|
-
const drift = checkClaudeMdDrift();
|
|
59
|
-
if (drift.drifted && drift.reason === 'content-changed') {
|
|
60
|
-
if (process.env.DEBUG) {
|
|
61
|
-
console.error('[session-start] CLAUDE.md drift detected — content changed since last sync');
|
|
62
|
-
}
|
|
63
|
-
driftDetected = true;
|
|
64
|
-
} else if (drift.drifted && drift.reason === 'marker-missing') {
|
|
65
|
-
if (process.env.DEBUG) {
|
|
66
|
-
console.error('[session-start] CLAUDE.md appears manually maintained (no generation marker)');
|
|
67
|
-
}
|
|
68
|
-
driftDetected = true;
|
|
69
|
-
driftMarkerMissing = true;
|
|
70
|
-
}
|
|
71
|
-
} catch (err) {
|
|
72
|
-
if (process.env.DEBUG) {
|
|
73
|
-
console.error(`[session-start] Drift detection failed: ${err.message}`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// --- Version compatibility checks (parallelized) ---
|
|
78
|
-
// 1. Claude Code: warns if below hard minimum (2.1.23) where hooks don't work
|
|
79
|
-
// 2. WogiFlow npm: warns if a newer version is available (checks once per 24h)
|
|
80
|
-
let versionWarning = null;
|
|
81
|
-
let updateWarning = null;
|
|
30
|
+
runHook('SessionStart', async ({ parsedInput }) => {
|
|
31
|
+
// Start bridge auto-sync in parallel with other init work
|
|
32
|
+
const bridgeSyncPromise = (async () => {
|
|
82
33
|
try {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
(async () => { try { return await checkClaudeCodeVersionOnce(); } catch (_err) { return null; } })(),
|
|
86
|
-
(async () => { try { return await checkWogiFlowUpdateOnce(); } catch (_err) { return null; } })()
|
|
87
|
-
]);
|
|
88
|
-
versionWarning = vw;
|
|
89
|
-
updateWarning = uw;
|
|
34
|
+
const syncFn = getAutoSyncBridge();
|
|
35
|
+
await syncFn('claude-code', { silent: true });
|
|
90
36
|
} catch (err) {
|
|
91
37
|
if (process.env.DEBUG) {
|
|
92
|
-
console.error(`[session-start]
|
|
38
|
+
console.error(`[session-start] Bridge auto-sync failed: ${err.message}`);
|
|
93
39
|
}
|
|
94
40
|
}
|
|
41
|
+
})();
|
|
95
42
|
|
|
96
|
-
|
|
97
|
-
|
|
43
|
+
// Wait for bridge sync to complete
|
|
44
|
+
await bridgeSyncPromise;
|
|
98
45
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
46
|
+
// CLAUDE.md drift detection — check if manually edited since last sync
|
|
47
|
+
let driftDetected = false;
|
|
48
|
+
let driftMarkerMissing = false;
|
|
49
|
+
try {
|
|
50
|
+
const { checkClaudeMdDrift } = require('../../../flow-bridge-state');
|
|
51
|
+
const drift = checkClaudeMdDrift();
|
|
52
|
+
if (drift.drifted && drift.reason === 'content-changed') {
|
|
53
|
+
if (process.env.DEBUG) {
|
|
54
|
+
console.error('[session-start] CLAUDE.md drift detected — content changed since last sync');
|
|
105
55
|
}
|
|
106
|
-
|
|
56
|
+
driftDetected = true;
|
|
57
|
+
} else if (drift.drifted && drift.reason === 'marker-missing') {
|
|
107
58
|
if (process.env.DEBUG) {
|
|
108
|
-
console.error(
|
|
59
|
+
console.error('[session-start] CLAUDE.md appears manually maintained (no generation marker)');
|
|
109
60
|
}
|
|
61
|
+
driftDetected = true;
|
|
62
|
+
driftMarkerMissing = true;
|
|
63
|
+
}
|
|
64
|
+
} catch (err) {
|
|
65
|
+
if (process.env.DEBUG) {
|
|
66
|
+
console.error(`[session-start] Drift detection failed: ${err.message}`);
|
|
110
67
|
}
|
|
68
|
+
}
|
|
111
69
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
70
|
+
// --- Version compatibility checks (parallelized) ---
|
|
71
|
+
let versionWarning = null;
|
|
72
|
+
let updateWarning = null;
|
|
73
|
+
try {
|
|
74
|
+
const { checkClaudeCodeVersionOnce, checkWogiFlowUpdateOnce } = require('../../../flow-version-check');
|
|
75
|
+
const [vw, uw] = await Promise.all([
|
|
76
|
+
(async () => { try { return await checkClaudeCodeVersionOnce(); } catch (_err) { return null; } })(),
|
|
77
|
+
(async () => { try { return await checkWogiFlowUpdateOnce(); } catch (_err) { return null; } })()
|
|
78
|
+
]);
|
|
79
|
+
versionWarning = vw;
|
|
80
|
+
updateWarning = uw;
|
|
81
|
+
} catch (err) {
|
|
82
|
+
if (process.env.DEBUG) {
|
|
83
|
+
console.error(`[session-start] Version check failed: ${err.message}`);
|
|
121
84
|
}
|
|
85
|
+
}
|
|
122
86
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
87
|
+
// --- Batch 1: Independent pre-context operations (async + sync) ---
|
|
88
|
+
let scriptWarnings = [];
|
|
89
|
+
try {
|
|
90
|
+
const wasReset = checkAndResetStalePhase();
|
|
91
|
+
if (wasReset && process.env.DEBUG) {
|
|
92
|
+
console.error('[session-start] Reset stale workflow phase to idle');
|
|
93
|
+
}
|
|
94
|
+
} catch (err) {
|
|
95
|
+
if (process.env.DEBUG) {
|
|
96
|
+
console.error(`[session-start] Failed to check stale phase: ${err.message}`);
|
|
130
97
|
}
|
|
98
|
+
}
|
|
131
99
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// archived but the task is still inProgress in ready.json.
|
|
137
|
-
try {
|
|
138
|
-
const { getReadyData } = require('../../../flow-utils');
|
|
139
|
-
const readyData = getReadyData();
|
|
140
|
-
if (Array.isArray(readyData.inProgress) && readyData.inProgress.length > 0) {
|
|
141
|
-
const task = readyData.inProgress[0];
|
|
142
|
-
const taskId = task && task.id;
|
|
143
|
-
if (taskId) {
|
|
144
|
-
const { loadDurableSession, createDurableSession } = require('../../../flow-durable-session');
|
|
145
|
-
const existing = loadDurableSession();
|
|
146
|
-
if (!existing || existing.taskId !== taskId) {
|
|
147
|
-
const criteria = task.acceptanceCriteria || task.scenarios || [];
|
|
148
|
-
const steps = Array.isArray(criteria) ? criteria : [];
|
|
149
|
-
const sessionSteps = steps.length > 0 ? steps : [task.title || taskId];
|
|
150
|
-
createDurableSession(taskId, 'task', sessionSteps);
|
|
151
|
-
if (process.env.DEBUG) {
|
|
152
|
-
console.error(`[session-start] Created durable session for active task ${taskId}`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
} catch (err) {
|
|
158
|
-
// Non-blocking — prompt capture is best-effort
|
|
159
|
-
if (process.env.DEBUG) {
|
|
160
|
-
console.error(`[session-start] Durable session init failed: ${err.message}`);
|
|
161
|
-
}
|
|
100
|
+
try {
|
|
101
|
+
const routingResult = setRoutingPending();
|
|
102
|
+
if (process.env.DEBUG) {
|
|
103
|
+
console.error(`[session-start] Set routing-pending: ${routingResult.reason}`);
|
|
162
104
|
}
|
|
105
|
+
} catch (err) {
|
|
106
|
+
if (process.env.DEBUG) {
|
|
107
|
+
console.error(`[session-start] Failed to set routing-pending: ${err.message}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
163
110
|
|
|
164
|
-
|
|
165
|
-
const
|
|
111
|
+
try {
|
|
112
|
+
const { validateScripts } = require('../../../flow-script-resolver');
|
|
113
|
+
scriptWarnings = validateScripts();
|
|
114
|
+
} catch (err) {
|
|
115
|
+
if (process.env.DEBUG) {
|
|
116
|
+
console.error(`[session-start] Script validation failed: ${err.message}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
166
119
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
120
|
+
// BUG-005 fix: Create durable-session.json for active tasks on session start.
|
|
121
|
+
try {
|
|
122
|
+
const { getReadyData } = require('../../../flow-utils');
|
|
123
|
+
const readyData = getReadyData();
|
|
124
|
+
if (Array.isArray(readyData.inProgress) && readyData.inProgress.length > 0) {
|
|
125
|
+
const task = readyData.inProgress[0];
|
|
126
|
+
const taskId = task && task.id;
|
|
127
|
+
if (taskId) {
|
|
128
|
+
const { loadDurableSession, createDurableSession } = require('../../../flow-durable-session');
|
|
129
|
+
const existing = loadDurableSession();
|
|
130
|
+
if (!existing || existing.taskId !== taskId) {
|
|
131
|
+
const criteria = task.acceptanceCriteria || task.scenarios || [];
|
|
132
|
+
const steps = Array.isArray(criteria) ? criteria : [];
|
|
133
|
+
const sessionSteps = steps.length > 0 ? steps : [task.title || taskId];
|
|
134
|
+
createDurableSession(taskId, 'task', sessionSteps);
|
|
170
135
|
if (process.env.DEBUG) {
|
|
171
|
-
console.error(`[session-start]
|
|
136
|
+
console.error(`[session-start] Created durable session for active task ${taskId}`);
|
|
172
137
|
}
|
|
173
|
-
}
|
|
174
|
-
|
|
138
|
+
}
|
|
139
|
+
}
|
|
175
140
|
}
|
|
141
|
+
} catch (err) {
|
|
142
|
+
if (process.env.DEBUG) {
|
|
143
|
+
console.error(`[session-start] Durable session init failed: ${err.message}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Async operations — batch with Promise.all
|
|
148
|
+
const asyncPreOps = [];
|
|
176
149
|
|
|
150
|
+
if (parsedInput.sessionId) {
|
|
177
151
|
asyncPreOps.push(
|
|
178
|
-
|
|
152
|
+
setCliSessionId(parsedInput.sessionId).catch(err => {
|
|
179
153
|
if (process.env.DEBUG) {
|
|
180
|
-
console.error(`[session-start] Failed to
|
|
154
|
+
console.error(`[session-start] Failed to store session ID: ${err.message}`);
|
|
181
155
|
}
|
|
182
156
|
})
|
|
183
157
|
);
|
|
158
|
+
}
|
|
184
159
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
160
|
+
asyncPreOps.push(
|
|
161
|
+
clearStaleCurrentTaskAsync().catch(err => {
|
|
162
|
+
if (process.env.DEBUG) {
|
|
163
|
+
console.error(`[session-start] Failed to clear stale task: ${err.message}`);
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
// Gather session context concurrently with the async pre-ops
|
|
169
|
+
const [, coreResult] = await Promise.all([
|
|
170
|
+
Promise.all(asyncPreOps),
|
|
171
|
+
gatherSessionContext({
|
|
172
|
+
includeSuspended: true,
|
|
173
|
+
includeDecisions: true,
|
|
174
|
+
includeActivity: true
|
|
175
|
+
})
|
|
176
|
+
]);
|
|
177
|
+
|
|
178
|
+
// --- Batch 2: Post-context operations (plugin scan + community pull) ---
|
|
179
|
+
const postContextOps = [];
|
|
180
|
+
|
|
181
|
+
// Plugin auto-scan (non-blocking)
|
|
182
|
+
postContextOps.push((async () => {
|
|
183
|
+
try {
|
|
184
|
+
const config = getConfig();
|
|
185
|
+
if (config.plugins?.enabled && config.plugins?.autoScanOnSessionStart) {
|
|
186
|
+
const { scanUnregisteredMcpServers, registerPlugin, deactivateStaleMcpPlugins, listPlugins } = require('../../../flow-plugin-registry');
|
|
187
|
+
|
|
188
|
+
const unregistered = scanUnregisteredMcpServers();
|
|
189
|
+
for (const server of unregistered) {
|
|
190
|
+
registerPlugin({
|
|
191
|
+
name: server.serverName,
|
|
192
|
+
description: `Auto-discovered MCP server: ${server.serverName}`,
|
|
193
|
+
source: 'auto-scan',
|
|
194
|
+
triggers: [`use ${server.serverName}`, `send to ${server.serverName}`, server.serverName],
|
|
195
|
+
capabilities: [],
|
|
196
|
+
metadata: { mcpServer: server.serverName }
|
|
197
|
+
});
|
|
198
|
+
if (process.env.DEBUG) {
|
|
199
|
+
console.error(`[session-start] Auto-registered plugin: ${server.serverName}`);
|
|
220
200
|
}
|
|
201
|
+
}
|
|
221
202
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
203
|
+
const deactivated = deactivateStaleMcpPlugins();
|
|
204
|
+
if (deactivated.length > 0 && process.env.DEBUG) {
|
|
205
|
+
console.error(`[session-start] Deactivated ${deactivated.length} stale plugin(s): ${deactivated.join(', ')}`);
|
|
206
|
+
}
|
|
226
207
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
208
|
+
if (coreResult && coreResult.context) {
|
|
209
|
+
const activePlugins = listPlugins({ activeOnly: true });
|
|
210
|
+
if (unregistered.length > 0 || activePlugins.length > 0) {
|
|
211
|
+
coreResult.context.pluginScan = {
|
|
212
|
+
newlyRegistered: unregistered.map(s => s.serverName),
|
|
213
|
+
activePlugins: activePlugins.map(p => ({ name: p.name, capabilities: (p.capabilities || []).length }))
|
|
214
|
+
};
|
|
235
215
|
}
|
|
236
216
|
}
|
|
237
|
-
} catch (err) {
|
|
238
|
-
if (process.env.DEBUG) {
|
|
239
|
-
console.error(`[session-start] Plugin auto-scan failed: ${err.message}`);
|
|
240
|
-
}
|
|
241
217
|
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if (communityConfig.community?.enabled) {
|
|
249
|
-
const community = require('../../../flow-community');
|
|
250
|
-
|
|
251
|
-
community.retryPendingSuggestions(communityConfig).catch(() => {});
|
|
252
|
-
|
|
253
|
-
if (communityConfig.community?.pullOnSessionStart !== false) {
|
|
254
|
-
const knowledge = await community.pullFromServer(communityConfig);
|
|
255
|
-
if (knowledge && coreResult && coreResult.context) {
|
|
256
|
-
coreResult.context.communityKnowledge = knowledge;
|
|
218
|
+
} catch (err) {
|
|
219
|
+
if (process.env.DEBUG) {
|
|
220
|
+
console.error(`[session-start] Plugin auto-scan failed: ${err.message}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
})());
|
|
257
224
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
225
|
+
// Community knowledge pull + suggestion retry (non-blocking)
|
|
226
|
+
postContextOps.push((async () => {
|
|
227
|
+
try {
|
|
228
|
+
const communityConfig = getConfig();
|
|
229
|
+
if (communityConfig.community?.enabled) {
|
|
230
|
+
const community = require('../../../flow-community');
|
|
231
|
+
|
|
232
|
+
community.retryPendingSuggestions(communityConfig).catch(() => {});
|
|
233
|
+
|
|
234
|
+
if (communityConfig.community?.pullOnSessionStart !== false) {
|
|
235
|
+
const knowledge = await community.pullFromServer(communityConfig);
|
|
236
|
+
if (knowledge && coreResult && coreResult.context) {
|
|
237
|
+
coreResult.context.communityKnowledge = knowledge;
|
|
238
|
+
|
|
239
|
+
try {
|
|
240
|
+
community.mergeCommunityKnowledge(knowledge, communityConfig);
|
|
241
|
+
} catch (err) {
|
|
242
|
+
if (process.env.DEBUG) {
|
|
243
|
+
console.error(`[session-start] Community merge failed: ${err.message}`);
|
|
264
244
|
}
|
|
265
245
|
}
|
|
266
246
|
}
|
|
267
247
|
}
|
|
268
|
-
} catch (err) {
|
|
269
|
-
if (process.env.DEBUG) {
|
|
270
|
-
console.error(`[session-start] Community pull failed: ${err.message}`);
|
|
271
|
-
}
|
|
272
248
|
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
// Inject script warnings into context (if any)
|
|
278
|
-
if (scriptWarnings.length > 0 && coreResult && coreResult.context) {
|
|
279
|
-
coreResult.context.scriptWarnings = scriptWarnings.map(w => w.message);
|
|
249
|
+
} catch (err) {
|
|
250
|
+
if (process.env.DEBUG) {
|
|
251
|
+
console.error(`[session-start] Community pull failed: ${err.message}`);
|
|
252
|
+
}
|
|
280
253
|
}
|
|
254
|
+
})());
|
|
281
255
|
|
|
282
|
-
|
|
283
|
-
if (versionWarning && coreResult && coreResult.context) {
|
|
284
|
-
coreResult.context.versionWarning = versionWarning;
|
|
285
|
-
}
|
|
256
|
+
await Promise.all(postContextOps);
|
|
286
257
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
258
|
+
// Inject script warnings into context (if any)
|
|
259
|
+
if (scriptWarnings.length > 0 && coreResult && coreResult.context) {
|
|
260
|
+
coreResult.context.scriptWarnings = scriptWarnings.map(w => w.message);
|
|
261
|
+
}
|
|
291
262
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
} else {
|
|
297
|
-
coreResult.context.driftWarning = 'CLAUDE.md content has changed since the last bridge sync. Was this intentional? If yes, WogiFlow will preserve your changes. If not, run `flow bridge sync` to regenerate from template.';
|
|
298
|
-
}
|
|
299
|
-
}
|
|
263
|
+
// Inject version compatibility warning (if any)
|
|
264
|
+
if (versionWarning && coreResult && coreResult.context) {
|
|
265
|
+
coreResult.context.versionWarning = versionWarning;
|
|
266
|
+
}
|
|
300
267
|
|
|
301
|
-
|
|
302
|
-
|
|
268
|
+
// Inject WogiFlow update warning (if any)
|
|
269
|
+
if (updateWarning && coreResult && coreResult.context) {
|
|
270
|
+
coreResult.context.updateWarning = updateWarning;
|
|
271
|
+
}
|
|
303
272
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
const { logHookError } = require('../../../flow-hook-errors');
|
|
311
|
-
logHookError('SessionStart', err, { failMode: 'open', operation: 'session-initialization' });
|
|
312
|
-
} catch (logErr) {
|
|
313
|
-
console.error(`[WogiFlow] SessionStart hook error: ${err.message}`);
|
|
273
|
+
// Inject drift detection results (if any)
|
|
274
|
+
if (driftDetected && coreResult && coreResult.context) {
|
|
275
|
+
if (driftMarkerMissing) {
|
|
276
|
+
coreResult.context.driftWarning = 'CLAUDE.md appears to have been manually edited (generation marker missing). Was this intentional? If yes, WogiFlow will respect your custom CLAUDE.md. If not, run `flow bridge sync` to regenerate from template.';
|
|
277
|
+
} else {
|
|
278
|
+
coreResult.context.driftWarning = 'CLAUDE.md content has changed since the last bridge sync. Was this intentional? If yes, WogiFlow will preserve your changes. If not, run `flow bridge sync` to regenerate from template.';
|
|
314
279
|
}
|
|
315
|
-
process.exit(1);
|
|
316
280
|
}
|
|
317
|
-
}
|
|
318
281
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
main();
|
|
282
|
+
return coreResult;
|
|
283
|
+
}, { failMode: 'warn' });
|
|
@@ -10,55 +10,14 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
const { handleSetup, handleMaintenance } = require('../../core/setup-handler');
|
|
13
|
-
const {
|
|
14
|
-
const { readHookInput } = require('../shared/read-stdin');
|
|
13
|
+
const { runHook } = require('../shared/hook-runner');
|
|
15
14
|
|
|
16
|
-
async
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const input = parsedStdin || {};
|
|
20
|
-
const parsedInput = claudeCodeAdapter.parseInput(input);
|
|
15
|
+
runHook('Setup', async ({ parsedInput }) => {
|
|
16
|
+
const trigger = parsedInput.source || 'init';
|
|
17
|
+
const isMaintenance = trigger === 'maintenance' || trigger === '--maintenance';
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const trigger = parsedInput.source || 'init';
|
|
25
|
-
const isMaintenance = trigger === 'maintenance' || trigger === '--maintenance';
|
|
26
|
-
|
|
27
|
-
let coreResult;
|
|
28
|
-
|
|
29
|
-
if (isMaintenance) {
|
|
30
|
-
// Run maintenance tasks
|
|
31
|
-
coreResult = handleMaintenance({
|
|
32
|
-
cwd: parsedInput.cwd
|
|
33
|
-
});
|
|
34
|
-
} else {
|
|
35
|
-
// Run setup check
|
|
36
|
-
coreResult = handleSetup({
|
|
37
|
-
trigger,
|
|
38
|
-
cwd: parsedInput.cwd
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Transform to Claude Code format
|
|
43
|
-
const output = claudeCodeAdapter.transformResult('Setup', coreResult);
|
|
44
|
-
|
|
45
|
-
// Output JSON
|
|
46
|
-
console.log(JSON.stringify(output));
|
|
47
|
-
process.exit(0);
|
|
48
|
-
} catch (err) {
|
|
49
|
-
// Non-blocking error - log to stderr, exit with allow
|
|
50
|
-
console.error(`[Wogi Flow Hook Error] ${err.message}`);
|
|
51
|
-
// Exit 0 with allow to not block on hook errors (graceful degradation)
|
|
52
|
-
console.log(JSON.stringify({
|
|
53
|
-
continue: true,
|
|
54
|
-
hookSpecificOutput: {
|
|
55
|
-
hookEventName: 'Setup'
|
|
56
|
-
}
|
|
57
|
-
}));
|
|
58
|
-
process.exit(0);
|
|
19
|
+
if (isMaintenance) {
|
|
20
|
+
return handleMaintenance({ cwd: parsedInput.cwd });
|
|
59
21
|
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Handle stdin properly
|
|
63
|
-
process.stdin.setEncoding('utf8');
|
|
64
|
-
main();
|
|
22
|
+
return handleSetup({ trigger, cwd: parsedInput.cwd });
|
|
23
|
+
}, { failMode: 'silent' });
|