wogiflow 2.20.1 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/wogi-finalize.md +83 -0
- package/.claude/rules/_internal/self-maintenance.md +1 -1
- package/.claude/settings.json +1 -1
- package/lib/commands/login.js +1 -1
- package/lib/installer.js +5 -5
- package/lib/release-channel.js +1 -1
- package/lib/skill-registry.js +3 -3
- package/lib/workspace-events.js +1 -1
- package/lib/workspace-gates.js +2 -2
- package/lib/workspace-intelligence.js +1 -1
- package/lib/workspace-routing.js +1 -1
- package/lib/workspace.js +16 -17
- package/package.json +2 -2
- package/scripts/base-workflow-step.js +2 -2
- package/scripts/flow-adaptive-learning.js +6 -6
- package/scripts/flow-api-index.js +2 -2
- package/scripts/flow-architect-pass.js +1 -1
- package/scripts/flow-ask.js +1 -1
- package/scripts/flow-assumption-detector.js +1 -1
- package/scripts/flow-audit-gates.js +38 -12
- package/scripts/flow-audit.js +4 -4
- package/scripts/flow-auto-context.js +3 -3
- package/scripts/flow-background.js +1 -1
- package/scripts/flow-best-of-n.js +7 -7
- package/scripts/flow-bridge.js +3 -3
- package/scripts/flow-bug.js +2 -2
- package/scripts/flow-bulk-loop.js +7 -7
- package/scripts/flow-cascade-completion.js +2 -2
- package/scripts/flow-cascade.js +1 -1
- package/scripts/flow-checkpoint.js +2 -2
- package/scripts/flow-clarifying-questions.js +2 -2
- package/scripts/flow-cli.js +2 -2
- package/scripts/flow-code-intelligence.js +4 -4
- package/scripts/flow-community-sync.js +6 -6
- package/scripts/flow-community.js +1 -1
- package/scripts/flow-completion-truth-gate.js +161 -5
- package/scripts/flow-complexity.js +1 -1
- package/scripts/flow-config-defaults.js +16 -4
- package/scripts/flow-config-interactive.js +2 -2
- package/scripts/flow-config-loader.js +1 -1
- package/scripts/flow-config-migrate.js +5 -6
- package/scripts/flow-consistency-check.js +5 -5
- package/scripts/flow-context-compact/expander.js +1 -1
- package/scripts/flow-context-compact/index.js +2 -2
- package/scripts/flow-context-compact/section-extractor.js +3 -3
- package/scripts/flow-context-compact/summary-tree.js +1 -1
- package/scripts/flow-context-estimator.js +1 -1
- package/scripts/flow-context-gatherer.js +6 -6
- package/scripts/flow-context-generator.js +6 -6
- package/scripts/flow-context-init.js +2 -2
- package/scripts/flow-context-manager.js +1 -1
- package/scripts/flow-context-manifest.js +1 -1
- package/scripts/flow-context-monitor.js +5 -5
- package/scripts/flow-context-orchestrator.js +2 -2
- package/scripts/flow-context-scoring.js +4 -4
- package/scripts/flow-contract-scan.js +1 -1
- package/scripts/flow-correct.js +3 -3
- package/scripts/flow-damage-control.js +2 -2
- package/scripts/flow-deploy-gate.js +2 -2
- package/scripts/flow-deploy-history.js +1 -1
- package/scripts/flow-diff.js +3 -3
- package/scripts/flow-done-gates.js +1 -1
- package/scripts/flow-done.js +7 -7
- package/scripts/flow-durable-session.js +1 -1
- package/scripts/flow-entropy-monitor.js +3 -3
- package/scripts/flow-epics.js +5 -5
- package/scripts/flow-error-recovery.js +4 -4
- package/scripts/flow-eval-judge.js +5 -5
- package/scripts/flow-eval.js +7 -7
- package/scripts/flow-export-scanner.js +5 -5
- package/scripts/flow-extraction-review.js +1 -1
- package/scripts/flow-failure-learning.js +9 -9
- package/scripts/flow-feature.js +5 -5
- package/scripts/flow-figma-confirm.js +1 -1
- package/scripts/flow-figma-extract.js +2 -2
- package/scripts/flow-figma-index.js +2 -2
- package/scripts/flow-figma-match.js +1 -1
- package/scripts/flow-figma-mcp-server.js +3 -3
- package/scripts/flow-figma-orchestrator.js +1 -1
- package/scripts/flow-figma-registry.js +2 -2
- package/scripts/flow-function-index.js +2 -2
- package/scripts/flow-gate-confidence.js +2 -2
- package/scripts/flow-gate-telemetry.js +1 -1
- package/scripts/flow-gitignore.js +1 -1
- package/scripts/flow-guided-edit.js +3 -3
- package/scripts/flow-health.js +95 -8
- package/scripts/flow-hooks.js +3 -3
- package/scripts/flow-hybrid-detect.js +2 -2
- package/scripts/flow-hybrid-interactive.js +1 -1
- package/scripts/flow-hybrid-test.js +1 -1
- package/scripts/flow-hypothesis-generator.js +4 -4
- package/scripts/flow-instruction-richness.js +11 -11
- package/scripts/flow-intent-bootstrap.js +1 -1
- package/scripts/flow-intent-framing.js +1 -1
- package/scripts/flow-item-link.js +2 -2
- package/scripts/flow-knowledge-router.js +7 -7
- package/scripts/flow-knowledge-sync.js +3 -3
- package/scripts/flow-learning-orchestrator.js +1 -1
- package/scripts/flow-links.js +2 -2
- package/scripts/flow-log-manager.js +2 -2
- package/scripts/flow-logic-adversary.js +5 -4
- package/scripts/flow-long-input-chunking.js +1 -1
- package/scripts/flow-long-input-cli.js +3 -3
- package/scripts/flow-long-input.js +18 -18
- package/scripts/flow-loop-retry-learning.js +2 -2
- package/scripts/flow-lsp.js +4 -4
- package/scripts/flow-mcp-docs.js +1 -1
- package/scripts/flow-memory-blocks.js +5 -5
- package/scripts/flow-memory-compactor.js +3 -3
- package/scripts/flow-memory-db.js +4 -4
- package/scripts/flow-memory-sync.js +3 -3
- package/scripts/flow-metrics.js +2 -2
- package/scripts/flow-migrate-igr.js +2 -2
- package/scripts/flow-migrate.js +2 -2
- package/scripts/flow-model-adapter.js +4 -4
- package/scripts/flow-model-caller.js +8 -8
- package/scripts/flow-model-config.js +5 -5
- package/scripts/flow-model-profile.js +7 -7
- package/scripts/flow-model-router.js +5 -5
- package/scripts/flow-model-types.js +3 -3
- package/scripts/flow-models.js +8 -8
- package/scripts/flow-morning.js +1 -1
- package/scripts/flow-multi-approach.js +1 -1
- package/scripts/flow-orchestrate-context.js +2 -2
- package/scripts/flow-orchestrate-llm.js +4 -4
- package/scripts/flow-orchestrate-rollback.js +1 -1
- package/scripts/flow-orchestrate-state.js +6 -6
- package/scripts/flow-orchestrate-templates.js +1 -1
- package/scripts/flow-orchestrate-validation.js +2 -2
- package/scripts/flow-orchestrate-validator.js +1 -1
- package/scripts/flow-orchestrate.js +25 -25
- package/scripts/flow-parallel.js +1 -1
- package/scripts/flow-pattern-enforcer.js +7 -7
- package/scripts/flow-pattern-extractor.js +3 -3
- package/scripts/flow-peer-review.js +8 -8
- package/scripts/flow-pending.js +1 -1
- package/scripts/flow-permissions.js +1 -1
- package/scripts/flow-phased-task.js +1 -1
- package/scripts/flow-plan.js +1 -1
- package/scripts/flow-prd-manager.js +2 -2
- package/scripts/flow-product-scanner.js +2 -2
- package/scripts/flow-progress-tracker.js +2 -2
- package/scripts/flow-progress.js +1 -1
- package/scripts/flow-project-analyzer.js +3 -3
- package/scripts/flow-prompt-capture.js +2 -2
- package/scripts/flow-prompt-composer.js +3 -3
- package/scripts/flow-prompt-template.js +4 -4
- package/scripts/flow-providers.js +31 -23
- package/scripts/flow-queue.js +1 -1
- package/scripts/flow-registry-manager.js +4 -4
- package/scripts/flow-regression.js +1 -1
- package/scripts/flow-response-parser.js +1 -1
- package/scripts/flow-resume.js +1 -1
- package/scripts/flow-review-passes/index.js +2 -2
- package/scripts/flow-review-passes/integration.js +3 -3
- package/scripts/flow-review-passes/logic.js +3 -3
- package/scripts/flow-review-passes/security.js +2 -2
- package/scripts/flow-review-passes/structure.js +1 -1
- package/scripts/flow-review.js +11 -11
- package/scripts/flow-revision-tracker.js +2 -2
- package/scripts/flow-roadmap.js +2 -2
- package/scripts/flow-run-trace.js +1 -1
- package/scripts/flow-safety.js +3 -3
- package/scripts/flow-scanner-base.js +1 -1
- package/scripts/flow-scenario-engine.js +7 -7
- package/scripts/flow-schema-drift.js +4 -3
- package/scripts/flow-section-index.js +2 -2
- package/scripts/flow-section-resolver.js +4 -4
- package/scripts/flow-semantic-match.js +3 -3
- package/scripts/flow-session-end.js +56 -0
- package/scripts/flow-session-learning.js +2 -2
- package/scripts/flow-setup-hooks.js +1 -1
- package/scripts/flow-skill-create.js +3 -3
- package/scripts/flow-skill-freshness.js +2 -2
- package/scripts/flow-skill-generator.js +6 -6
- package/scripts/flow-skill-learn.js +7 -7
- package/scripts/flow-skill-matcher.js +2 -2
- package/scripts/flow-solution-optimizer.js +1 -1
- package/scripts/flow-spec-generator.js +5 -5
- package/scripts/flow-spec-verifier.js +2 -2
- package/scripts/flow-stack-wizard.js +6 -6
- package/scripts/flow-standards-checker.js +8 -8
- package/scripts/flow-standards-gate.js +4 -4
- package/scripts/flow-standards-learner.js +2 -2
- package/scripts/flow-start.js +9 -9
- package/scripts/flow-stats-collector.js +2 -2
- package/scripts/flow-status.js +1 -1
- package/scripts/flow-step-changelog.js +3 -3
- package/scripts/flow-step-complexity.js +1 -1
- package/scripts/flow-step-coverage.js +3 -3
- package/scripts/flow-step-knowledge.js +2 -2
- package/scripts/flow-step-pr-tests.js +2 -2
- package/scripts/flow-step-regression.js +3 -3
- package/scripts/flow-step-review.js +5 -5
- package/scripts/flow-story.js +2 -2
- package/scripts/flow-strict-adherence.js +2 -2
- package/scripts/flow-structure-sensor.js +283 -0
- package/scripts/flow-sync-anonymizer.js +3 -3
- package/scripts/flow-task-checkpoint.js +2 -2
- package/scripts/flow-task-classifier.js +2 -2
- package/scripts/flow-task-completion-summary.js +1 -1
- package/scripts/flow-task-enforcer.js +5 -5
- package/scripts/flow-tech-debt.js +3 -3
- package/scripts/flow-template-extractor.js +3 -3
- package/scripts/flow-templates.js +1 -1
- package/scripts/flow-test-api.js +12 -12
- package/scripts/flow-test-discovery.js +9 -9
- package/scripts/flow-test-generate.js +5 -5
- package/scripts/flow-test-integrity.js +3 -3
- package/scripts/flow-test-ui.js +8 -8
- package/scripts/flow-testing-deps.js +4 -4
- package/scripts/flow-tiered-learning.js +3 -3
- package/scripts/flow-todowrite-sync.js +1 -1
- package/scripts/flow-trap-zone.js +1 -1
- package/scripts/flow-verification-profile.js +9 -9
- package/scripts/flow-verify.js +2 -2
- package/scripts/flow-version-check.js +2 -2
- package/scripts/flow-webmcp-generator.js +3 -3
- package/scripts/flow-wiring-verifier.js +13 -13
- package/scripts/flow-worker-question-classifier.js +256 -0
- package/scripts/flow-workflow-steps.js +3 -3
- package/scripts/flow-workflow.js +1 -1
- package/scripts/flow-worktree.js +1 -1
- package/scripts/hooks/adapters/base-adapter.js +2 -2
- package/scripts/hooks/core/commit-log-gate.js +2 -2
- package/scripts/hooks/core/component-check.js +3 -3
- package/scripts/hooks/core/config-change.js +1 -1
- package/scripts/hooks/core/deploy-gate.js +2 -1
- package/scripts/hooks/core/git-safety-gate.js +1 -1
- package/scripts/hooks/core/instructions-loaded.js +1 -1
- package/scripts/hooks/core/loop-check.js +1 -1
- package/scripts/hooks/core/manager-boundary-gate.js +3 -2
- package/scripts/hooks/core/observation-capture.js +6 -6
- package/scripts/hooks/core/phase-gate.js +4 -4
- package/scripts/hooks/core/pre-compact.js +1 -1
- package/scripts/hooks/core/pre-tool-orchestrator.js +1 -1
- package/scripts/hooks/core/routing-gate.js +2 -84
- package/scripts/hooks/core/session-context.js +1 -1
- package/scripts/hooks/core/session-end.js +3 -3
- package/scripts/hooks/core/session-history.js +1 -1
- package/scripts/hooks/core/setup-handler.js +1 -1
- package/scripts/hooks/core/task-boundary-reset.js +2 -4
- package/scripts/hooks/core/task-completed.js +13 -7
- package/scripts/hooks/core/task-created.js +1 -1
- package/scripts/hooks/core/worktree-lifecycle.js +1 -1
- package/scripts/hooks/entry/claude-code/permission-denied.js +4 -2
- package/scripts/hooks/entry/claude-code/stop.js +60 -0
- package/scripts/hooks/entry/claude-code/user-prompt-submit.js +1 -1
- package/scripts/hooks/git/post-commit.js +1 -1
- package/scripts/postinstall.js +7 -7
- package/scripts/preuninstall.js +5 -5
- package/scripts/registries/component-registry.js +2 -2
- package/scripts/registries/contract-scanner.js +11 -11
- package/scripts/registries/schema-registry.js +5 -5
- package/scripts/registries/service-registry.js +9 -9
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
* flow best-of-n config Show Best-of-N configuration
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
const
|
|
17
|
+
const _path = require('node:path');
|
|
18
18
|
const {
|
|
19
19
|
getConfig,
|
|
20
|
-
PATHS,
|
|
21
|
-
readJson,
|
|
20
|
+
PATHS: _PATHS,
|
|
21
|
+
readJson: _readJson,
|
|
22
22
|
validateTaskId
|
|
23
23
|
} = require('./flow-utils');
|
|
24
|
-
const {
|
|
24
|
+
const { analyzeComplexity } = require('./flow-task-analyzer');
|
|
25
25
|
|
|
26
26
|
// ============================================================
|
|
27
27
|
// Constants
|
|
@@ -108,7 +108,7 @@ function assessRisk(params) {
|
|
|
108
108
|
factors.push(`Medium complexity + many files`);
|
|
109
109
|
if (riskLevel !== 'high') riskLevel = 'medium';
|
|
110
110
|
}
|
|
111
|
-
} catch (
|
|
111
|
+
} catch (_err) {
|
|
112
112
|
// Non-critical — analyzer may not fully parse
|
|
113
113
|
}
|
|
114
114
|
|
|
@@ -242,7 +242,7 @@ function parseSelectionResponse(response) {
|
|
|
242
242
|
try {
|
|
243
243
|
const parsed = JSON.parse(response.trim());
|
|
244
244
|
if (parsed.winner && parsed.scores) return parsed;
|
|
245
|
-
} catch (
|
|
245
|
+
} catch (_err) {
|
|
246
246
|
// Not direct JSON
|
|
247
247
|
}
|
|
248
248
|
|
|
@@ -252,7 +252,7 @@ function parseSelectionResponse(response) {
|
|
|
252
252
|
try {
|
|
253
253
|
const parsed = JSON.parse(jsonMatch[0]);
|
|
254
254
|
if (parsed.winner && parsed.scores) return parsed;
|
|
255
|
-
} catch (
|
|
255
|
+
} catch (_err) {
|
|
256
256
|
// Failed to parse
|
|
257
257
|
}
|
|
258
258
|
}
|
package/scripts/flow-bridge.js
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
|
|
12
12
|
const fs = require('node:fs');
|
|
13
13
|
const path = require('node:path');
|
|
14
|
-
const { colors, getConfig, PROJECT_ROOT
|
|
15
|
-
const { success, warn, error
|
|
14
|
+
const { colors, getConfig, PROJECT_ROOT } = require('./flow-utils');
|
|
15
|
+
const { success, warn, error } = require('./flow-output');
|
|
16
16
|
|
|
17
17
|
const { PACKAGE_PATHS } = require('./flow-paths');
|
|
18
18
|
const BRIDGES_DIR = PACKAGE_PATHS.bridges;
|
|
@@ -129,7 +129,7 @@ async function syncBridge(options = {}) {
|
|
|
129
129
|
let bridges;
|
|
130
130
|
try {
|
|
131
131
|
bridges = require(path.join(BRIDGES_DIR, 'index.js'));
|
|
132
|
-
} catch (
|
|
132
|
+
} catch (_err) {
|
|
133
133
|
error('Bridges module not found.');
|
|
134
134
|
console.error('Make sure .workflow/bridges/index.js exists.');
|
|
135
135
|
process.exit(1);
|
package/scripts/flow-bug.js
CHANGED
|
@@ -19,7 +19,7 @@ const fs = require('node:fs');
|
|
|
19
19
|
const path = require('node:path');
|
|
20
20
|
const {
|
|
21
21
|
PATHS,
|
|
22
|
-
fileExists,
|
|
22
|
+
fileExists: _fileExists,
|
|
23
23
|
dirExists,
|
|
24
24
|
writeFile,
|
|
25
25
|
writeJson,
|
|
@@ -269,7 +269,7 @@ Examples:
|
|
|
269
269
|
const discoveredDuring = currentTask ? 'implementation' : null;
|
|
270
270
|
|
|
271
271
|
// Determine priority
|
|
272
|
-
const
|
|
272
|
+
const _config = getConfig();
|
|
273
273
|
const defaultPriority = getConfigValue('priorities.defaultPriority', 'P2');
|
|
274
274
|
|
|
275
275
|
let priority = flags.priority;
|
|
@@ -14,19 +14,19 @@
|
|
|
14
14
|
* - Graceful shutdown on Ctrl+C
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
const
|
|
17
|
+
const _path = require('node:path');
|
|
18
18
|
const {
|
|
19
19
|
PATHS,
|
|
20
20
|
PROJECT_ROOT,
|
|
21
|
-
getConfig,
|
|
21
|
+
getConfig: _getConfig,
|
|
22
22
|
safeJsonParse,
|
|
23
23
|
writeJson,
|
|
24
|
-
fileExists,
|
|
24
|
+
fileExists: _fileExists,
|
|
25
25
|
readFile
|
|
26
26
|
} = require('./flow-utils')
|
|
27
27
|
const { color, success, warn, error } = require('./flow-output');;
|
|
28
28
|
|
|
29
|
-
const {
|
|
29
|
+
const { } = require('./flow-durable-session');
|
|
30
30
|
|
|
31
31
|
// ============================================================================
|
|
32
32
|
// Constants
|
|
@@ -140,7 +140,7 @@ function getInProgressTask() {
|
|
|
140
140
|
const readyData = safeJsonParse(PATHS.ready, {});
|
|
141
141
|
const inProgress = getArraySafe(readyData, 'inProgress');
|
|
142
142
|
return inProgress.length > 0 ? inProgress[0] : null;
|
|
143
|
-
} catch (
|
|
143
|
+
} catch (_err) {
|
|
144
144
|
return null;
|
|
145
145
|
}
|
|
146
146
|
}
|
|
@@ -163,7 +163,7 @@ function getNextReadyTask() {
|
|
|
163
163
|
});
|
|
164
164
|
|
|
165
165
|
return sorted[0];
|
|
166
|
-
} catch (
|
|
166
|
+
} catch (_err) {
|
|
167
167
|
return null;
|
|
168
168
|
}
|
|
169
169
|
}
|
|
@@ -184,7 +184,7 @@ function getNextCapture() {
|
|
|
184
184
|
);
|
|
185
185
|
|
|
186
186
|
return captures.length > 0 ? captures[0] : null;
|
|
187
|
-
} catch (
|
|
187
|
+
} catch (_err) {
|
|
188
188
|
return null;
|
|
189
189
|
}
|
|
190
190
|
}
|
|
@@ -21,7 +21,7 @@ let flowPlan;
|
|
|
21
21
|
try {
|
|
22
22
|
flowFeature = require('./flow-feature');
|
|
23
23
|
flowPlan = require('./flow-plan');
|
|
24
|
-
} catch (
|
|
24
|
+
} catch (_err) {
|
|
25
25
|
// Modules optional - graceful degradation
|
|
26
26
|
flowFeature = null;
|
|
27
27
|
flowPlan = null;
|
|
@@ -149,7 +149,7 @@ function allFeaturesComplete(epic) {
|
|
|
149
149
|
if (!isComplete) return false;
|
|
150
150
|
}
|
|
151
151
|
return true;
|
|
152
|
-
} catch (
|
|
152
|
+
} catch (_err) {
|
|
153
153
|
return false;
|
|
154
154
|
}
|
|
155
155
|
}
|
package/scripts/flow-cascade.js
CHANGED
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
|
|
23
23
|
const fs = require('node:fs');
|
|
24
24
|
const path = require('node:path');
|
|
25
|
-
const {
|
|
26
|
-
const {
|
|
25
|
+
const { spawnSync } = require('node:child_process');
|
|
26
|
+
const { getConfig, colors: c, PATHS } = require('./flow-utils');
|
|
27
27
|
const { success: printSuccess, warn: printWarn } = require('./flow-output');
|
|
28
28
|
|
|
29
29
|
const CHECKPOINTS_DIR = PATHS.checkpoints;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
const path = require('node:path');
|
|
15
15
|
const {
|
|
16
16
|
PATHS,
|
|
17
|
-
readJson,
|
|
17
|
+
readJson: _readJson,
|
|
18
18
|
readFile,
|
|
19
19
|
fileExists,
|
|
20
20
|
parseFlags,
|
|
@@ -171,7 +171,7 @@ function assessComplexity(context) {
|
|
|
171
171
|
* @returns {Object[]} Array of questions with category and text
|
|
172
172
|
*/
|
|
173
173
|
function generateQuestions(context, options = {}) {
|
|
174
|
-
const
|
|
174
|
+
const _config = getConfig();
|
|
175
175
|
const maxQuestions = options.maxQuestions ||
|
|
176
176
|
getConfigValue('clarifyingQuestions.maxQuestions', 5);
|
|
177
177
|
const skipForSmall = options.skipForSmall ??
|
package/scripts/flow-cli.js
CHANGED
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
* cli.fail('Something went wrong', 1);
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
const
|
|
26
|
-
const
|
|
25
|
+
const _fs = require('node:fs');
|
|
26
|
+
const _path = require('node:path');
|
|
27
27
|
const { colors: c, parseFlags: utilsParseFlags } = require('./flow-utils');
|
|
28
28
|
const { success: outputSuccess, warn: outputWarn, error: outputError, info: outputInfo } = require('./flow-output');
|
|
29
29
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
const fs = require('node:fs');
|
|
20
20
|
const path = require('node:path');
|
|
21
|
-
const {
|
|
21
|
+
const { getConfig, PATHS, colors, readJson } = require('./flow-utils');
|
|
22
22
|
const { success, error: errorMsg } = require('./flow-output');
|
|
23
23
|
const { safeGrep, safeFind, escapeRegex } = require('./flow-security');
|
|
24
24
|
|
|
@@ -105,7 +105,7 @@ function analyzeRelationships(filePath) {
|
|
|
105
105
|
/**
|
|
106
106
|
* Extract imports from file content
|
|
107
107
|
*/
|
|
108
|
-
function extractImports(content,
|
|
108
|
+
function extractImports(content, _fileDir) {
|
|
109
109
|
const imports = [];
|
|
110
110
|
|
|
111
111
|
// ES6 imports
|
|
@@ -456,7 +456,7 @@ async function searchCodebase(keyword, maxResults = 10) {
|
|
|
456
456
|
* Generate enhanced component index with relationships
|
|
457
457
|
*/
|
|
458
458
|
async function generateEnhancedIndex() {
|
|
459
|
-
const
|
|
459
|
+
const _config = getConfig();
|
|
460
460
|
const indexPath = path.join(PATHS.state, 'component-index.json');
|
|
461
461
|
|
|
462
462
|
// Read existing index
|
|
@@ -514,7 +514,7 @@ async function generateEnhancedIndex() {
|
|
|
514
514
|
* @param {object} options - Options
|
|
515
515
|
*/
|
|
516
516
|
async function getSmartContext(taskDescription, options = {}) {
|
|
517
|
-
const
|
|
517
|
+
const _config = getConfig();
|
|
518
518
|
const indexPath = path.join(PATHS.state, 'component-index.json');
|
|
519
519
|
|
|
520
520
|
if (!fs.existsSync(indexPath)) {
|
|
@@ -22,10 +22,10 @@ const {
|
|
|
22
22
|
PATHS,
|
|
23
23
|
readJson,
|
|
24
24
|
writeJson,
|
|
25
|
-
fileExists,
|
|
25
|
+
fileExists: _fileExists,
|
|
26
26
|
getTodayDate
|
|
27
27
|
} = require('./flow-utils');
|
|
28
|
-
const {
|
|
28
|
+
const { createUploadPayload } = require('./flow-sync-anonymizer');
|
|
29
29
|
const { loadStats } = require('./flow-stats-collector');
|
|
30
30
|
|
|
31
31
|
// ============================================================
|
|
@@ -84,7 +84,7 @@ function isSyncEnabled() {
|
|
|
84
84
|
if (!fs.existsSync(authPath)) return false;
|
|
85
85
|
const auth = readJson(authPath, {});
|
|
86
86
|
return !!(auth.token || auth.apiKey);
|
|
87
|
-
} catch (
|
|
87
|
+
} catch (_err) {
|
|
88
88
|
return false;
|
|
89
89
|
}
|
|
90
90
|
}
|
|
@@ -293,7 +293,7 @@ function getQueueStatus() {
|
|
|
293
293
|
? queue.payloads[0].queuedAt
|
|
294
294
|
: null
|
|
295
295
|
};
|
|
296
|
-
} catch (
|
|
296
|
+
} catch (_err) {
|
|
297
297
|
return { queuedSessions: 0, lastUpdated: null };
|
|
298
298
|
}
|
|
299
299
|
}
|
|
@@ -324,7 +324,7 @@ function loadCommunityScores() {
|
|
|
324
324
|
try {
|
|
325
325
|
if (!fs.existsSync(COMMUNITY_SCORES_PATH)) return {};
|
|
326
326
|
return readJson(COMMUNITY_SCORES_PATH, {});
|
|
327
|
-
} catch (
|
|
327
|
+
} catch (_err) {
|
|
328
328
|
return {};
|
|
329
329
|
}
|
|
330
330
|
}
|
|
@@ -338,7 +338,7 @@ function loadCommunityRouting() {
|
|
|
338
338
|
try {
|
|
339
339
|
if (!fs.existsSync(COMMUNITY_ROUTING_PATH)) return {};
|
|
340
340
|
return readJson(COMMUNITY_ROUTING_PATH, {});
|
|
341
|
-
} catch (
|
|
341
|
+
} catch (_err) {
|
|
342
342
|
return {};
|
|
343
343
|
}
|
|
344
344
|
}
|
|
@@ -888,7 +888,7 @@ const COMMUNITY_MARKER = '<!-- community-knowledge-v1 -->';
|
|
|
888
888
|
* @param {Object} config - WogiFlow config
|
|
889
889
|
* @returns {{ modelIntelligence: number, errorStrategies: number, patterns: number }} Merge counts
|
|
890
890
|
*/
|
|
891
|
-
function mergeCommunityKnowledge(knowledge,
|
|
891
|
+
function mergeCommunityKnowledge(knowledge, _config) {
|
|
892
892
|
const counts = { modelIntelligence: 0, errorStrategies: 0, patterns: 0 };
|
|
893
893
|
if (!knowledge || typeof knowledge !== 'object') return counts;
|
|
894
894
|
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
* const safeText = downgradeClaim('Task is done.', audit);
|
|
41
41
|
*/
|
|
42
42
|
|
|
43
|
-
const
|
|
44
|
-
const
|
|
43
|
+
const _fs = require('node:fs');
|
|
44
|
+
const _path = require('node:path');
|
|
45
45
|
|
|
46
|
-
const {
|
|
47
|
-
const {
|
|
46
|
+
const { } = require('./flow-paths');
|
|
47
|
+
const { } = require('./flow-io');
|
|
48
48
|
const { getConfig } = require('./flow-config-loader');
|
|
49
|
-
const {
|
|
49
|
+
const { } = require('./flow-output');
|
|
50
50
|
|
|
51
51
|
const gateTelemetry = require('./flow-gate-telemetry');
|
|
52
52
|
|
|
@@ -460,6 +460,160 @@ function recordTelemetry(verdict, runCtx = {}) {
|
|
|
460
460
|
});
|
|
461
461
|
}
|
|
462
462
|
|
|
463
|
+
// ============================================================
|
|
464
|
+
// Claim-vs-state contradiction scanner (2026-04-16 honesty-infra review)
|
|
465
|
+
// ============================================================
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Done-words must be preceded by a negation to qualify as a "no outage" claim.
|
|
469
|
+
* We keep the list narrow to avoid false positives on routine phrasing.
|
|
470
|
+
*/
|
|
471
|
+
const NEGATION_PREFIXES = /\b(?:no|zero|0|without(?: any)?|not a single)\s+/i;
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* State-disagreement words a user would recognize as "the work did NOT go cleanly":
|
|
475
|
+
* hotfix/hotfixes (committed after-the-fact repair), regression, outage, incident,
|
|
476
|
+
* P0/P1, rollback, revert. Regex is intentionally anchored so "incidentally" does
|
|
477
|
+
* not match.
|
|
478
|
+
*/
|
|
479
|
+
const DISAGREEMENT_WORDS = ['outage', 'outages', 'incident', 'incidents', 'regression', 'regressions', 'rollback', 'rollbacks', 'revert', 'reverts', 'hotfix', 'hotfixes'];
|
|
480
|
+
const DISAGREEMENT_RE = new RegExp(`\\b(?:${DISAGREEMENT_WORDS.join('|')})\\b`, 'i');
|
|
481
|
+
|
|
482
|
+
const PARTIAL_STATUSES = new Set(['completed-partial', 'completed_partial', 'partial', 'in-progress', 'in_progress', 'blocked', 'failed']);
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Scan a task-shaped object (from ready.json, completed-archive.json, or a durable
|
|
486
|
+
* session snapshot) for contradictions between its free-text claim fields and its
|
|
487
|
+
* structured state fields.
|
|
488
|
+
*
|
|
489
|
+
* Free-text fields scanned: `notes`, `result`, `summary`, `description`.
|
|
490
|
+
* Structured fields inspected: `status`, `childTasks[].hotfixes`, `hotfixes`,
|
|
491
|
+
* `incidents`, `regressions`.
|
|
492
|
+
*
|
|
493
|
+
* Two contradiction classes:
|
|
494
|
+
* A) **done-word vs partial-status** — notes say "shipped end-to-end" while
|
|
495
|
+
* status is "completed-partial". If the notes claim completion but the
|
|
496
|
+
* status is not `completed`, emit a contradiction.
|
|
497
|
+
* B) **negated-disagreement vs evidence-of-disagreement** — result says
|
|
498
|
+
* "0 outages" while `childTasks[].hotfixes` is non-empty, or notes say
|
|
499
|
+
* "no regressions" while a `regressions` array has entries.
|
|
500
|
+
*
|
|
501
|
+
* Return shape:
|
|
502
|
+
* {
|
|
503
|
+
* contradictions: [
|
|
504
|
+
* { class: 'A'|'B', field, snippet, structuralEvidence, suggestion }, ...
|
|
505
|
+
* ],
|
|
506
|
+
* scanned: true,
|
|
507
|
+
* reason: '...' // when scanned=false (e.g., input not a task)
|
|
508
|
+
* }
|
|
509
|
+
*
|
|
510
|
+
* @param {Object} task - task-shaped object
|
|
511
|
+
* @returns {Object}
|
|
512
|
+
*/
|
|
513
|
+
function scanForClaimContradictions(task) {
|
|
514
|
+
if (!task || typeof task !== 'object' || Array.isArray(task)) {
|
|
515
|
+
return { contradictions: [], scanned: false, reason: 'not-a-task-object' };
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
const contradictions = [];
|
|
519
|
+
const freeTextFields = ['notes', 'result', 'summary', 'description'];
|
|
520
|
+
|
|
521
|
+
const status = String(task.status || '').toLowerCase().trim();
|
|
522
|
+
const isPartial = PARTIAL_STATUSES.has(status);
|
|
523
|
+
|
|
524
|
+
// Evidence that the work hit real disagreement (would invalidate "0 outages" claims).
|
|
525
|
+
const hotfixes = collectArrayEntries(task, ['hotfixes', 'incidents', 'regressions']);
|
|
526
|
+
const childHotfixes = Array.isArray(task.childTasks)
|
|
527
|
+
? task.childTasks.flatMap((c) => collectArrayEntries(c, ['hotfixes', 'incidents', 'regressions']))
|
|
528
|
+
: [];
|
|
529
|
+
const hasDisagreementEvidence = hotfixes.length > 0 || childHotfixes.length > 0;
|
|
530
|
+
|
|
531
|
+
for (const field of freeTextFields) {
|
|
532
|
+
const text = extractText(task[field]);
|
|
533
|
+
if (!text) continue;
|
|
534
|
+
|
|
535
|
+
// Class A: done-word + partial status
|
|
536
|
+
if (isPartial) {
|
|
537
|
+
const hit = findDoneWordHit(text);
|
|
538
|
+
if (hit) {
|
|
539
|
+
contradictions.push({
|
|
540
|
+
class: 'A',
|
|
541
|
+
field,
|
|
542
|
+
snippet: snippetAround(text, hit.index, hit.word.length),
|
|
543
|
+
structuralEvidence: `task.status = "${task.status}"`,
|
|
544
|
+
suggestion: `Reconcile: either update status to "completed" (if actually done) or soften the ${field} wording (e.g., "implemented" / "partially shipped")`,
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Class B: negated-disagreement + evidence of disagreement
|
|
550
|
+
if (hasDisagreementEvidence) {
|
|
551
|
+
const bHit = findNegatedDisagreement(text);
|
|
552
|
+
if (bHit) {
|
|
553
|
+
const evidenceSummary = [
|
|
554
|
+
hotfixes.length > 0 ? `task.hotfixes/incidents/regressions has ${hotfixes.length} entry(ies)` : null,
|
|
555
|
+
childHotfixes.length > 0 ? `childTasks[].hotfixes has ${childHotfixes.length} entry(ies)` : null,
|
|
556
|
+
].filter(Boolean).join(' + ');
|
|
557
|
+
contradictions.push({
|
|
558
|
+
class: 'B',
|
|
559
|
+
field,
|
|
560
|
+
snippet: snippetAround(text, bHit.index, bHit.length),
|
|
561
|
+
structuralEvidence: evidenceSummary,
|
|
562
|
+
suggestion: `Either remove the negation (e.g., "one hotfix resolved in X min" instead of "0 outages") or move the disagreement entries off this task`,
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
return { contradictions, scanned: true };
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function extractText(value) {
|
|
572
|
+
if (typeof value === 'string') return value;
|
|
573
|
+
if (Array.isArray(value)) return value.map(extractText).filter(Boolean).join(' ');
|
|
574
|
+
return '';
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
function findDoneWordHit(text) {
|
|
578
|
+
const re = new RegExp(`\\b(?:${DONE_WORDS.join('|')})\\b(?:\\s+end-to-end)?`, 'i');
|
|
579
|
+
const m = re.exec(text);
|
|
580
|
+
if (!m) return null;
|
|
581
|
+
return { word: m[0], index: m.index };
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
function findNegatedDisagreement(text) {
|
|
585
|
+
// Walk every occurrence of a disagreement word and check if it's preceded
|
|
586
|
+
// (within the same sentence, up to ~40 chars) by a negation prefix.
|
|
587
|
+
const re = new RegExp(`\\b(${DISAGREEMENT_WORDS.join('|')})\\b`, 'gi');
|
|
588
|
+
let m;
|
|
589
|
+
while ((m = re.exec(text)) !== null) {
|
|
590
|
+
const windowStart = Math.max(0, m.index - 40);
|
|
591
|
+
const window = text.slice(windowStart, m.index);
|
|
592
|
+
if (NEGATION_PREFIXES.test(window)) {
|
|
593
|
+
return { index: m.index, length: m[0].length };
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
return null;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
function snippetAround(text, index, length) {
|
|
600
|
+
const start = Math.max(0, index - 30);
|
|
601
|
+
const end = Math.min(text.length, index + length + 30);
|
|
602
|
+
const prefix = start > 0 ? '…' : '';
|
|
603
|
+
const suffix = end < text.length ? '…' : '';
|
|
604
|
+
return `${prefix}${text.slice(start, end).replace(/\s+/g, ' ').trim()}${suffix}`;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
function collectArrayEntries(obj, keys) {
|
|
608
|
+
if (!obj || typeof obj !== 'object') return [];
|
|
609
|
+
const out = [];
|
|
610
|
+
for (const k of keys) {
|
|
611
|
+
const v = obj[k];
|
|
612
|
+
if (Array.isArray(v)) out.push(...v.filter((x) => x !== null && x !== undefined && x !== ''));
|
|
613
|
+
}
|
|
614
|
+
return out;
|
|
615
|
+
}
|
|
616
|
+
|
|
463
617
|
// ============================================================
|
|
464
618
|
// Exports
|
|
465
619
|
// ============================================================
|
|
@@ -472,6 +626,8 @@ module.exports = {
|
|
|
472
626
|
getStepEvidence,
|
|
473
627
|
isTruthGateDisabled,
|
|
474
628
|
getMinTierForDone,
|
|
629
|
+
scanForClaimContradictions,
|
|
475
630
|
TIER_NAMES,
|
|
476
631
|
DONE_WORDS,
|
|
632
|
+
DISAGREEMENT_WORDS,
|
|
477
633
|
};
|
|
@@ -369,7 +369,7 @@ function assessTaskComplexity(task) {
|
|
|
369
369
|
/**
|
|
370
370
|
* Generates human-readable reasoning
|
|
371
371
|
*/
|
|
372
|
-
function generateReasoning(level, factors,
|
|
372
|
+
function generateReasoning(level, factors, _breakdown) {
|
|
373
373
|
const parts = [];
|
|
374
374
|
|
|
375
375
|
// File summary
|
|
@@ -399,10 +399,14 @@ const CONFIG_DEFAULTS = {
|
|
|
399
399
|
managerCanSkipGates: false,
|
|
400
400
|
_comment_autoPickupChannelDispatches: 'v2.20.0+: After task completion, if channel-dispatched tasks are queued in ready.json, the task-completed hook injects additionalContext instructing the AI to auto-invoke /wogi-start on the next queued task in the same turn. Prevents "Sauteed worker" silent stalls between queued dispatches. The Stop hook also blocks end-of-turn when queued dispatches exist but no task is in progress — making "awaiting signal" language mechanically impossible as a terminal state.',
|
|
401
401
|
autoPickupChannelDispatches: true,
|
|
402
|
-
_comment_diagnosticCurlBypass: 'v2.20.0+: When true, PreToolUse routing gate allows narrow curl-to-manager-port when replying to channel messages tagged INTROSPECTION or DIAGNOSTIC, with body starting "## ". Unblocks diagnostic round-trips without forcing fake task creation. Scope: localhost:8800 only.',
|
|
403
|
-
diagnosticCurlBypass: true,
|
|
404
402
|
_comment_blockAskUserQuestionInWorker: 'v2.20.1+: When true, PreToolUse blocks AskUserQuestion in workspace worker mode. The user only sees the manager terminal, so direct prompts from workers stall silently. Block message instructs channel-dispatch "## QUESTION:" to the manager. Closes the v2.20.0 gap where workers could still prompt the user directly when their queue was empty.',
|
|
405
|
-
blockAskUserQuestionInWorker: true
|
|
403
|
+
blockAskUserQuestionInWorker: true,
|
|
404
|
+
_comment_aiWorkerQuestionClassifier: 'v2.21.0+: When true, Stop hook runs a Haiku classifier on the final assistant message in worker mode. If the message ends by asking the user a question (detected semantically, not via regex), the stop is blocked with channel-dispatch instructions. Degrades to no-op when ANTHROPIC_API_KEY is absent. Uses existing flow-model-caller infrastructure.',
|
|
405
|
+
aiWorkerQuestionClassifier: {
|
|
406
|
+
enabled: true,
|
|
407
|
+
minConfidence: 70,
|
|
408
|
+
model: 'anthropic:claude-3-5-haiku-latest'
|
|
409
|
+
}
|
|
406
410
|
},
|
|
407
411
|
checkpoint: { enabled: false },
|
|
408
412
|
regressionTesting: { enabled: false },
|
|
@@ -733,7 +737,15 @@ const CONFIG_DEFAULTS = {
|
|
|
733
737
|
autoMergeForTypes: ['bugfix', 'quick-fix'],
|
|
734
738
|
requirePRForTypes: [],
|
|
735
739
|
squashOnMerge: true,
|
|
736
|
-
prTemplate: { includeTaskSpec: true, includeCommitList: true, includeFileSummary: true }
|
|
740
|
+
prTemplate: { includeTaskSpec: true, includeCommitList: true, includeFileSummary: true },
|
|
741
|
+
// Merge-plan gate: require .workflow/scratch/merge-plan.md for large or cross-repo merges.
|
|
742
|
+
// See .claude/commands/wogi-finalize.md §Step 2.5. Added 2026-04-16.
|
|
743
|
+
mergePlan: {
|
|
744
|
+
enabled: true,
|
|
745
|
+
threshold: 5,
|
|
746
|
+
restructureThreshold: 0.20,
|
|
747
|
+
alwaysForCrossRepo: true
|
|
748
|
+
}
|
|
737
749
|
},
|
|
738
750
|
|
|
739
751
|
// --- Models ---
|
|
@@ -22,7 +22,7 @@ const {
|
|
|
22
22
|
getConfig,
|
|
23
23
|
color,
|
|
24
24
|
success,
|
|
25
|
-
warn,
|
|
25
|
+
warn: _warn,
|
|
26
26
|
error,
|
|
27
27
|
parseFlags,
|
|
28
28
|
outputJson,
|
|
@@ -286,7 +286,7 @@ function main() {
|
|
|
286
286
|
execFileSync(process.execPath, [path.join(__dirname, 'flow-config-set.js'), key, value], {
|
|
287
287
|
stdio: 'inherit'
|
|
288
288
|
});
|
|
289
|
-
} catch (
|
|
289
|
+
} catch (_err) {
|
|
290
290
|
process.exit(1);
|
|
291
291
|
}
|
|
292
292
|
break;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
const fs = require('node:fs');
|
|
12
12
|
const path = require('node:path');
|
|
13
13
|
const { PATHS, PROJECT_ROOT, isPathWithinProject } = require('./flow-paths');
|
|
14
|
-
const {
|
|
14
|
+
const { writeJson, acquireLock, safeJsonParse, safeJsonParseString } = require('./flow-io');
|
|
15
15
|
const { warn } = require('./flow-output');
|
|
16
16
|
|
|
17
17
|
// Late-loaded to avoid circular dependency
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
const fs = require('node:fs');
|
|
22
|
-
const
|
|
22
|
+
const _path = require('node:path');
|
|
23
|
+
const { safeJsonParse } = require('./flow-io');
|
|
23
24
|
|
|
24
25
|
/** Current config version — increment when adding new migrations */
|
|
25
26
|
const CURRENT_CONFIG_VERSION = 2;
|
|
@@ -232,12 +233,10 @@ function migrateConfigFile(configPath) {
|
|
|
232
233
|
return { migrated: false, fromVersion: 0, toVersion: 0, applied: [] };
|
|
233
234
|
}
|
|
234
235
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
238
|
-
} catch (err) {
|
|
236
|
+
const config = safeJsonParse(configPath, null);
|
|
237
|
+
if (!config) {
|
|
239
238
|
if (process.env.DEBUG) {
|
|
240
|
-
console.error(`[config-migrate] Failed to read config
|
|
239
|
+
console.error(`[config-migrate] Failed to read config at ${configPath}`);
|
|
241
240
|
}
|
|
242
241
|
return { migrated: false, fromVersion: 0, toVersion: 0, applied: [] };
|
|
243
242
|
}
|
|
@@ -34,8 +34,8 @@ const {
|
|
|
34
34
|
getConfig,
|
|
35
35
|
success,
|
|
36
36
|
warn,
|
|
37
|
-
error,
|
|
38
|
-
safeJsonParse,
|
|
37
|
+
error: _error,
|
|
38
|
+
safeJsonParse: _safeJsonParse,
|
|
39
39
|
isPathWithinProject
|
|
40
40
|
} = require('./flow-utils');
|
|
41
41
|
|
|
@@ -338,7 +338,7 @@ function getSourceFiles() {
|
|
|
338
338
|
let entries;
|
|
339
339
|
try {
|
|
340
340
|
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
341
|
-
} catch (
|
|
341
|
+
} catch (_err) {
|
|
342
342
|
return;
|
|
343
343
|
}
|
|
344
344
|
|
|
@@ -402,7 +402,7 @@ function checkFileExists(entry) {
|
|
|
402
402
|
* @param {Object} [options] - Options
|
|
403
403
|
* @returns {Object} Check results
|
|
404
404
|
*/
|
|
405
|
-
function runConsistencyCheck(
|
|
405
|
+
function runConsistencyCheck(_options = {}) {
|
|
406
406
|
const config = getConfig();
|
|
407
407
|
const consistencyConfig = config.consistency || {};
|
|
408
408
|
|
|
@@ -426,7 +426,7 @@ function runConsistencyCheck(options = {}) {
|
|
|
426
426
|
const appMapEntries = checks.appMapVsCodebase !== false || checks.orphanDetection !== false ? parseAppMap() : [];
|
|
427
427
|
const functionMapEntries = checks.functionMapVsCodebase !== false || checks.orphanDetection !== false ? parseFunctionMap() : [];
|
|
428
428
|
const apiMapEntries = checks.apiMapVsCodebase !== false || checks.orphanDetection !== false ? parseApiMap() : [];
|
|
429
|
-
const
|
|
429
|
+
const _additionalEntries = checks.orphanDetection !== false ? parseAdditionalRegistryMaps() : [];
|
|
430
430
|
|
|
431
431
|
// 1. App-map vs codebase
|
|
432
432
|
if (checks.appMapVsCodebase !== false) {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
const path = require('node:path');
|
|
17
17
|
const { getConfig, readJson, writeJson, ensureDir, PATHS } = require('../flow-utils');
|
|
18
|
-
const { loadTree,
|
|
18
|
+
const { loadTree, estimateTokens, calculateTreeTokens } = require('./summary-tree');
|
|
19
19
|
const { scoreNodeRelevance, extractKeywords } = require('./section-extractor');
|
|
20
20
|
|
|
21
21
|
// ============================================================
|
|
@@ -141,14 +141,14 @@ function cleanupPlanFiles() {
|
|
|
141
141
|
try {
|
|
142
142
|
const stats = fs.lstatSync(filePath);
|
|
143
143
|
if (stats.isSymbolicLink()) continue;
|
|
144
|
-
} catch (
|
|
144
|
+
} catch (_err) {
|
|
145
145
|
continue;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
let content;
|
|
149
149
|
try {
|
|
150
150
|
content = fs.readFileSync(filePath, 'utf-8');
|
|
151
|
-
} catch (
|
|
151
|
+
} catch (_err) {
|
|
152
152
|
continue; // Skip files we can't read
|
|
153
153
|
}
|
|
154
154
|
|