wogiflow 2.26.2 → 2.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/wogi-bug.md +30 -0
- package/.claude/commands/wogi-debug-hypothesis.md +33 -0
- package/.claude/commands/wogi-morning.md +1 -2
- package/.claude/commands/wogi-review.md +31 -2
- package/.claude/commands/wogi-start.md +32 -0
- package/.claude/commands/wogi-statusline-setup.md +12 -0
- package/.claude/commands/wogi-story.md +3 -2
- package/.claude/docs/claude-code-compatibility.md +40 -0
- package/.claude/docs/phases/01-explore.md +2 -1
- package/.claude/docs/phases/03-implement.md +4 -0
- package/.claude/docs/phases/04-verify.md +45 -0
- package/.claude/rules/README.md +36 -0
- package/.claude/rules/_internal/worker-tool-first-turn.md +82 -0
- package/.claude/rules/alternative-execpolicy-toml-command-policy.md +11 -0
- package/.claude/rules/alternative-hand-edit-ready-json-to-register-orpha.md +11 -0
- package/.claude/rules/alternative-permission-ruleset-per-phase.md +11 -0
- package/.claude/rules/alternative-short-name.md +12 -0
- package/.claude/rules/alternative-wogi-flow-as-mcp-client-oauth-manager.md +11 -0
- package/.claude/rules/architecture/hook-three-layer.md +68 -0
- package/.claude/rules/dual-repo-architecture-2026-02-28.md +18 -0
- package/.claude/rules/github-release-workflow-2026-01-30.md +16 -0
- package/.claude/settings.json +1 -1
- package/.workflow/agents/logic-adversary.md +2 -1
- package/.workflow/agents/personas/README.md +48 -0
- package/.workflow/agents/personas/platform-rigor.md +38 -0
- package/.workflow/agents/personas/scale-skeptic.md +28 -0
- package/.workflow/agents/personas/security-hawk.md +34 -0
- package/.workflow/agents/personas/simplicity-champion.md +37 -0
- package/.workflow/agents/personas/user-advocate.md +36 -0
- package/.workflow/bridges/base-bridge.js +46 -23
- package/.workflow/templates/claude-md.hbs +44 -122
- package/.workflow/templates/partials/feature-dossiers.hbs +33 -0
- package/.workflow/templates/partials/intent-grounded-reasoning.hbs +2 -12
- package/.workflow/templates/partials/methodology-rules.hbs +85 -79
- package/.workflow/templates/tier3-dom-field-inventory.md +102 -0
- package/lib/fuzzy-patch.js +251 -0
- package/lib/installer.js +8 -0
- package/lib/memory-proposal-store.js +458 -0
- package/lib/mode-schema.js +255 -0
- package/lib/skill-proposal-store.js +432 -0
- package/lib/skill-registry.js +1 -1
- package/lib/wogi-claude +149 -9
- package/lib/wogi-claude-expect.exp +113 -76
- package/lib/workspace-channel-server.js +19 -0
- package/lib/workspace-contracts.js +1 -1
- package/lib/workspace-dispatch-tracking.js +144 -0
- package/lib/workspace-gates.js +1 -1
- package/lib/workspace-ipc-sqlite.js +550 -0
- package/lib/workspace-messages.js +92 -0
- package/lib/workspace-routing.js +1 -1
- package/lib/workspace-task-injector.js +223 -0
- package/lib/workspace.js +23 -0
- package/lib/worktree-review.js +315 -0
- package/package.json +2 -2
- package/scripts/base-workflow-step.js +1 -1
- package/scripts/flow +28 -4
- package/scripts/flow-ac-scope-preservation.js +238 -0
- package/scripts/flow-auto-review-worker.js +75 -0
- package/scripts/flow-auto-review.js +102 -0
- package/scripts/flow-autonomous-detector.js +118 -0
- package/scripts/flow-autonomous-mode.js +153 -0
- package/scripts/flow-best-of-n.js +1 -1
- package/scripts/flow-bulk-loop.js +1 -1
- package/scripts/flow-checkpoint.js +2 -6
- package/scripts/flow-community-sync.js +1 -1
- package/scripts/flow-completion-summary.js +176 -0
- package/scripts/flow-completion-truth-gate.js +343 -4
- package/scripts/flow-config-defaults.js +52 -5
- package/scripts/flow-config-loader.js +3 -2
- package/scripts/flow-context-compact/expander.js +1 -1
- package/scripts/flow-context-compact/section-extractor.js +2 -2
- package/scripts/flow-context-gatherer.js +1 -1
- package/scripts/flow-context-generator.js +1 -1
- package/scripts/flow-context-scoring.js +1 -1
- package/scripts/flow-correct.js +1 -1
- package/scripts/flow-correction-detector.js +3 -2
- package/scripts/flow-decision-authority.js +66 -15
- package/scripts/flow-done.js +33 -1
- package/scripts/flow-epic-cascade.js +171 -0
- package/scripts/flow-epics.js +2 -7
- package/scripts/flow-eval-judge.js +1 -1
- package/scripts/flow-eval.js +1 -1
- package/scripts/flow-export-scanner.js +2 -6
- package/scripts/flow-failure-learning.js +1 -1
- package/scripts/flow-feature-dossier.js +787 -0
- package/scripts/flow-figma-extract.js +2 -2
- package/scripts/flow-figma-generate.js +1 -1
- package/scripts/flow-gate-confidence.js +1 -1
- package/scripts/flow-health.js +52 -1
- package/scripts/flow-hooks.js +1 -1
- package/scripts/flow-id.js +19 -3
- package/scripts/flow-instruction-richness.js +1 -1
- package/scripts/flow-knowledge-router.js +1 -1
- package/scripts/flow-knowledge-sync.js +1 -1
- package/scripts/flow-logic-adversary.js +76 -1
- package/scripts/flow-logic-rules.js +380 -0
- package/scripts/flow-long-input.js +5 -5
- package/scripts/flow-memory-sync.js +1 -1
- package/scripts/flow-memory.js +78 -7
- package/scripts/flow-migrate.js +1 -1
- package/scripts/flow-model-caller.js +1 -1
- package/scripts/flow-models.js +2 -2
- package/scripts/flow-morning.js +0 -17
- package/scripts/flow-multi-approach.js +1 -1
- package/scripts/flow-orchestrate-context.js +4 -4
- package/scripts/flow-orchestrate-templates.js +1 -1
- package/scripts/flow-orchestrate.js +8 -8
- package/scripts/flow-peer-review.js +1 -1
- package/scripts/flow-phase.js +9 -0
- package/scripts/flow-proactive-compact.js +1 -1
- package/scripts/flow-prompt-composer.js +3 -2
- package/scripts/flow-prompt-template.js +3 -2
- package/scripts/flow-providers.js +1 -1
- package/scripts/flow-question-queue.js +255 -0
- package/scripts/flow-repo-map.js +312 -0
- package/scripts/flow-review-passes/index.js +1 -1
- package/scripts/flow-review-passes/integration.js +1 -1
- package/scripts/flow-review-passes/structure.js +1 -1
- package/scripts/flow-revision-tracker.js +1 -1
- package/scripts/flow-section-resolver.js +1 -1
- package/scripts/flow-session-end.js +74 -5
- package/scripts/flow-session-state.js +103 -1
- package/scripts/flow-setup-hooks.js +1 -1
- package/scripts/flow-skeptical-evaluator.js +274 -0
- package/scripts/flow-skill-generator.js +3 -3
- package/scripts/flow-skill-learn.js +3 -6
- package/scripts/flow-skill-manage.js +248 -0
- package/scripts/flow-spec-verifier.js +1 -1
- package/scripts/flow-standards-checker.js +75 -0
- package/scripts/flow-standards-gate.js +1 -1
- package/scripts/flow-statusline-setup.js +8 -2
- package/scripts/flow-step-changelog.js +2 -2
- package/scripts/flow-step-coverage.js +1 -1
- package/scripts/flow-step-knowledge.js +1 -1
- package/scripts/flow-step-regression.js +1 -1
- package/scripts/flow-step-simplifier.js +1 -1
- package/scripts/flow-task-analyzer.js +1 -1
- package/scripts/flow-task-classifier.js +1 -1
- package/scripts/flow-task-enforcer.js +1 -1
- package/scripts/flow-template-extractor.js +1 -1
- package/scripts/flow-trap-zone.js +1 -1
- package/scripts/flow-utils.js +4 -0
- package/scripts/flow-worker-mcp-strip.js +122 -0
- package/scripts/flow-worker-question-classifier.js +51 -5
- package/scripts/flow-workspace-migrate-ipc.js +216 -0
- package/scripts/flow-workspace-summary.js +256 -0
- package/scripts/hooks/adapters/base-adapter.js +2 -2
- package/scripts/hooks/core/feature-dossier-gate.js +194 -0
- package/scripts/hooks/core/observation-capture.js +24 -0
- package/scripts/hooks/core/overdue-dispatches.js +20 -1
- package/scripts/hooks/core/phase-gate.js +15 -1
- package/scripts/hooks/core/phase-transition-auto-review.js +61 -0
- package/scripts/hooks/core/post-compact.js +5 -2
- package/scripts/hooks/core/pre-tool-orchestrator.js +21 -0
- package/scripts/hooks/core/routing-gate.js +58 -0
- package/scripts/hooks/core/session-context.js +108 -0
- package/scripts/hooks/core/session-end-memory-proposals.js +65 -0
- package/scripts/hooks/core/session-end-skill-proposals.js +58 -0
- package/scripts/hooks/core/session-end.js +25 -0
- package/scripts/hooks/core/setup-handler.js +1 -1
- package/scripts/hooks/core/task-boundary-reset.js +110 -4
- package/scripts/hooks/core/worker-boundary-gate.js +71 -0
- package/scripts/hooks/core/worker-tool-first-gate.js +275 -0
- package/scripts/hooks/entry/claude-code/post-tool-use.js +2 -2
- package/scripts/hooks/entry/claude-code/pre-tool-use.js +7 -2
- package/scripts/hooks/entry/claude-code/session-start.js +74 -30
- package/scripts/hooks/entry/claude-code/stop.js +47 -1
- package/scripts/hooks/entry/claude-code/user-prompt-submit.js +17 -0
- package/.workflow/templates/partials/user-commands.hbs +0 -20
|
@@ -52,17 +52,17 @@ const {
|
|
|
52
52
|
// Destructure parsing functions
|
|
53
53
|
const {
|
|
54
54
|
parseVTT: _parseVTT, parseSRT: _parseSRT, parseSubtitle: _parseSubtitle, mergeCues: _mergeCues, formatCuesAsText: _formatCuesAsText, getSubtitleStats: _getSubtitleStats,
|
|
55
|
-
parseZoom: _parseZoom, parseTeams: _parseTeams, parseMeeting: _parseMeeting, mergeMeetingEntries: _mergeMeetingEntries, formatMeetingAsText: _formatMeetingAsText,
|
|
55
|
+
parseZoom: _parseZoom, parseTeams: _parseTeams, parseMeeting: _parseMeeting, mergeMeetingEntries: _mergeMeetingEntries, formatMeetingAsText: _formatMeetingAsText, _getMeetingStats
|
|
56
56
|
} = transcriptParsing;
|
|
57
57
|
|
|
58
58
|
// Destructure chunking functions
|
|
59
59
|
const {
|
|
60
60
|
loadDurableSessions: _loadDurableSessions, listDurableSessions: _listDurableSessions, getDurableSession: _getDurableSession, switchDurableSession: _switchDurableSession,
|
|
61
61
|
archiveDurableSession: _archiveDurableSession, deleteDurableSession: _deleteDurableSession, generateRecoverySummaryForSession: _generateRecoverySummaryForSession,
|
|
62
|
-
getTimeSince: _getTimeSince, needsChunking: _needsChunking, planChunks: _planChunks,
|
|
62
|
+
getTimeSince: _getTimeSince, needsChunking: _needsChunking, planChunks: _planChunks, _getChunkingStatus
|
|
63
63
|
} = transcriptChunking;
|
|
64
64
|
|
|
65
|
-
const {
|
|
65
|
+
const { _listSupportedLanguages } = transcriptLanguage;
|
|
66
66
|
|
|
67
67
|
// Destructure story functions
|
|
68
68
|
const {
|
|
@@ -72,7 +72,7 @@ const {
|
|
|
72
72
|
formatActionsPrompt: _formatActionsPrompt, getCompletionSummary: _getCompletionSummary, resetPresentation: _resetPresentation,
|
|
73
73
|
startEditSession: _startEditSession, editUserStory: _editUserStory, editCriterion: _editCriterion, addCriterion: _addCriterion, removeCriterion: _removeCriterion,
|
|
74
74
|
getEditChanges: _getEditChanges, commitEditSession: _commitEditSession, cancelEditSession: _cancelEditSession, getEditHistory: _getEditHistory, listEditableStories: _listEditableStories,
|
|
75
|
-
previewExport: _previewExport, exportApprovedStories: _exportApprovedStories,
|
|
75
|
+
previewExport: _previewExport, exportApprovedStories: _exportApprovedStories, _finalizeDigestion
|
|
76
76
|
} = transcriptStories;
|
|
77
77
|
|
|
78
78
|
// Destructure constants
|
|
@@ -81,7 +81,7 @@ const {
|
|
|
81
81
|
CORRECTION_PATTERNS: _CORRECTION_PATTERNS, ADDITIVE_PATTERNS: _ADDITIVE_PATTERNS,
|
|
82
82
|
ENTITY_PATTERNS, VAGUE_PATTERNS, QUESTION_TEMPLATES,
|
|
83
83
|
DETAIL_PATTERNS, QUESTION_TEMPLATES_BY_LANGUAGE, FOLLOWUP_TRIGGERS,
|
|
84
|
-
UI_PATTERNS: _UI_PATTERNS, DATA_PATTERNS: _DATA_PATTERNS, INTERACTION_PATTERNS: _INTERACTION_PATTERNS,
|
|
84
|
+
UI_PATTERNS: _UI_PATTERNS, DATA_PATTERNS: _DATA_PATTERNS, INTERACTION_PATTERNS: _INTERACTION_PATTERNS, _COMPLEXITY_LEVELS
|
|
85
85
|
} = longInputConstants;
|
|
86
86
|
|
|
87
87
|
// Destructure voice functions
|
package/scripts/flow-memory.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Wogi Flow - Memory CLI (query / fetch / stats / tag)
|
|
4
|
+
* Wogi Flow - Memory CLI (query / fetch / stats / tag / propose)
|
|
5
5
|
*
|
|
6
6
|
* Unified query layer over WogiFlow's state-file landscape. Instead of
|
|
7
7
|
* grepping across ready.json / decisions.md / feedback-patterns.md /
|
|
@@ -9,9 +9,13 @@
|
|
|
9
9
|
* `flow memory query <filters>` or `flow memory fetch <ref>`.
|
|
10
10
|
*
|
|
11
11
|
* Story: wf-e64cacd0 (epic-episodic-memory, re-scoped post-pivot).
|
|
12
|
+
* Story: wf-4434851f (IGR artifact edit proposals — propose|approve|reject|list).
|
|
12
13
|
*
|
|
13
14
|
* Boundaries:
|
|
14
|
-
* - Does NOT modify
|
|
15
|
+
* - Does NOT modify query source files.
|
|
16
|
+
* - The propose/approve surface stages edits to IGR artifacts
|
|
17
|
+
* (product / domain-model / user-journeys / glossary). Agents propose;
|
|
18
|
+
* the user approves at session-end. No silent writes.
|
|
15
19
|
* - Tags are stored in a sidecar `.workflow/state/memory-tags.json` — the
|
|
16
20
|
* source memory files stay immutable.
|
|
17
21
|
*
|
|
@@ -21,6 +25,10 @@
|
|
|
21
25
|
* flow memory stats
|
|
22
26
|
* flow memory tag <ref> <#tag>
|
|
23
27
|
* flow memory untag <ref> <#tag>
|
|
28
|
+
* flow memory propose --block <b> --op <o> --content <file> [--section <h>] [--rationale <text>]
|
|
29
|
+
* flow memory approve <id>
|
|
30
|
+
* flow memory reject <id> [--reason <text>]
|
|
31
|
+
* flow memory list [--status pending|approved|rejected] [--json]
|
|
24
32
|
*
|
|
25
33
|
* Usage (programmatic):
|
|
26
34
|
* const { queryMemory, fetchByRef, memoryStats, addTag } = require('./flow-memory');
|
|
@@ -749,15 +757,78 @@ if (require.main === module) {
|
|
|
749
757
|
return;
|
|
750
758
|
}
|
|
751
759
|
|
|
760
|
+
if (cmd === 'propose' || cmd === 'approve' || cmd === 'reject' || cmd === 'list') {
|
|
761
|
+
const store = require('../lib/memory-proposal-store');
|
|
762
|
+
try {
|
|
763
|
+
if (cmd === 'propose') {
|
|
764
|
+
const record = store.createProposal({
|
|
765
|
+
block: args.block,
|
|
766
|
+
op: args.op,
|
|
767
|
+
contentFile: args.content,
|
|
768
|
+
section: args.section,
|
|
769
|
+
rationale: args.rationale,
|
|
770
|
+
proposedBy: args['proposed-by'],
|
|
771
|
+
});
|
|
772
|
+
if (args.json) { console.log(JSON.stringify(record, null, 2)); return; }
|
|
773
|
+
console.log(`Staged ${record.op} on ${record.block} (${record.id})`);
|
|
774
|
+
console.log(` content: ${record.contentPath}`);
|
|
775
|
+
if (record.section) console.log(` section: ${record.section}`);
|
|
776
|
+
if (record.rationale) console.log(` rationale: ${record.rationale}`);
|
|
777
|
+
console.log(` review at session-end or: flow memory list`);
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
if (cmd === 'approve') {
|
|
781
|
+
const id = args._[1] || args.id;
|
|
782
|
+
if (!id) { console.error('Usage: flow memory approve <id>'); process.exit(1); }
|
|
783
|
+
const applied = store.approveProposal({ id });
|
|
784
|
+
if (args.json) { console.log(JSON.stringify(applied, null, 2)); return; }
|
|
785
|
+
console.log(`Approved ${applied.op} on ${applied.block} (${applied.id})`);
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
if (cmd === 'reject') {
|
|
789
|
+
const id = args._[1] || args.id;
|
|
790
|
+
if (!id) { console.error('Usage: flow memory reject <id> [--reason <text>]'); process.exit(1); }
|
|
791
|
+
const rejected = store.rejectProposal({ id, reason: args.reason });
|
|
792
|
+
if (args.json) { console.log(JSON.stringify(rejected, null, 2)); return; }
|
|
793
|
+
console.log(`Rejected ${rejected.op} on ${rejected.block} (${rejected.id})`);
|
|
794
|
+
if (rejected.reason) console.log(` reason: ${rejected.reason}`);
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
// list
|
|
798
|
+
const statusFilter = args.status && args.status !== true ? args.status : 'pending';
|
|
799
|
+
const list = store.listProposals({ status: statusFilter });
|
|
800
|
+
if (args.json) { console.log(JSON.stringify(list, null, 2)); return; }
|
|
801
|
+
if (list.length === 0) { console.log(`(no ${statusFilter} memory proposals)`); return; }
|
|
802
|
+
console.log(`Memory proposals (${statusFilter}, ${list.length}):`);
|
|
803
|
+
for (const r of list) {
|
|
804
|
+
const icon = r.op === 'append' ? '+' : r.op === 'replace-section' ? '~' : '!';
|
|
805
|
+
console.log(` ${icon} ${r.block} [${r.op}] ${r.id}`);
|
|
806
|
+
console.log(` proposedAt: ${r.proposedAt} by: ${r.proposedBy}`);
|
|
807
|
+
if (r.section) console.log(` section: ${r.section}`);
|
|
808
|
+
if (r.rationale) console.log(` rationale: ${r.rationale}`);
|
|
809
|
+
}
|
|
810
|
+
return;
|
|
811
|
+
} catch (err) {
|
|
812
|
+
console.error(`[memory:${cmd}] error: ${err.message}`);
|
|
813
|
+
process.exit(1);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
|
|
752
817
|
console.log(`Usage:
|
|
753
|
-
flow memory query
|
|
754
|
-
flow memory fetch
|
|
755
|
-
flow memory stats
|
|
756
|
-
flow memory tag
|
|
757
|
-
flow memory untag
|
|
818
|
+
flow memory query [--since=<dur>] [--task=<id>] [--kind=<k>] [--tag=<#t>] [--limit=N] [--json]
|
|
819
|
+
flow memory fetch <ref> [--raw] [--json]
|
|
820
|
+
flow memory stats [--json]
|
|
821
|
+
flow memory tag <ref> <#tag>
|
|
822
|
+
flow memory untag <ref> <#tag>
|
|
823
|
+
flow memory propose --block <b> --op <o> --content <file> [--section <h>] [--rationale <text>]
|
|
824
|
+
flow memory approve <id>
|
|
825
|
+
flow memory reject <id> [--reason <text>]
|
|
826
|
+
flow memory list [--status pending|approved|rejected] [--json]
|
|
758
827
|
|
|
759
828
|
Durations: 30m, 2h, 7d, 2w
|
|
760
829
|
Kinds: ${Object.values(KINDS).join(', ')}
|
|
830
|
+
Blocks: product, domain-model, user-journeys, glossary
|
|
831
|
+
Ops: append, replace-section, replace-all (replace-all requires --rationale)
|
|
761
832
|
Refs: wf-XXXXXXXX | R-NNN | CORR-NNN | <adversary-run-filename>`);
|
|
762
833
|
process.exit(cmd ? 1 : 0);
|
|
763
834
|
})().catch((err) => {
|
package/scripts/flow-migrate.js
CHANGED
package/scripts/flow-models.js
CHANGED
|
@@ -545,7 +545,7 @@ function getCostAnalysis(_options = {}) {
|
|
|
545
545
|
}
|
|
546
546
|
|
|
547
547
|
// Generate recommendations using CONFIG constants
|
|
548
|
-
for (const [
|
|
548
|
+
for (const [_modelId, modelData] of Object.entries(analysis.byModel)) {
|
|
549
549
|
if (modelData.costTier === 'premium' && modelData.totalTasks > CONFIG.MIN_TASKS_FOR_RECOMMENDATION) {
|
|
550
550
|
const avgCost = modelData.avgCostPerTask;
|
|
551
551
|
if (avgCost > CONFIG.COST_OPTIMIZATION_THRESHOLD) {
|
|
@@ -826,7 +826,7 @@ function formatCostAnalysis(analysis) {
|
|
|
826
826
|
const sortedModels = Object.entries(analysis.byModel)
|
|
827
827
|
.sort((a, b) => b[1].totalCost - a[1].totalCost);
|
|
828
828
|
|
|
829
|
-
for (const [
|
|
829
|
+
for (const [_modelId, data] of sortedModels) {
|
|
830
830
|
output += ` ${color('cyan', data.displayName)} (${data.costTier})\n`;
|
|
831
831
|
output += ` Total: $${data.totalCost.toFixed(4)} | Tasks: ${data.totalTasks} | Avg: $${data.avgCostPerTask.toFixed(4)}\n`;
|
|
832
832
|
}
|
package/scripts/flow-morning.js
CHANGED
|
@@ -649,23 +649,6 @@ function printBriefing(briefing) {
|
|
|
649
649
|
function main() {
|
|
650
650
|
const { flags } = parseFlags(process.argv.slice(2));
|
|
651
651
|
|
|
652
|
-
// Check if morning briefing is enabled
|
|
653
|
-
const config = getConfig();
|
|
654
|
-
const morningConfig = config.morningBriefing || {};
|
|
655
|
-
|
|
656
|
-
if (morningConfig.enabled === false) {
|
|
657
|
-
if (flags.json) {
|
|
658
|
-
outputJson({
|
|
659
|
-
success: false,
|
|
660
|
-
error: 'Morning briefing is disabled in config',
|
|
661
|
-
hint: 'Set morningBriefing.enabled: true in .workflow/config.json'
|
|
662
|
-
});
|
|
663
|
-
}
|
|
664
|
-
console.log(color('yellow', 'Morning briefing is disabled.'));
|
|
665
|
-
console.log(color('dim', 'Enable it in .workflow/config.json: morningBriefing.enabled: true'));
|
|
666
|
-
process.exit(0);
|
|
667
|
-
}
|
|
668
|
-
|
|
669
652
|
// v2.6.1: Clean up stale state before briefing (safety net)
|
|
670
653
|
// Morning briefing also cleans up stale auto-created tasks older than 24h
|
|
671
654
|
const cleanedState = cleanupStaleState({ cleanupStaleTasks: true });
|
|
@@ -220,7 +220,7 @@ function calculateApproachScore(result) {
|
|
|
220
220
|
if (result.code) score += 10;
|
|
221
221
|
|
|
222
222
|
// Validation gates
|
|
223
|
-
for (const [
|
|
223
|
+
for (const [_gate, passed] of Object.entries(result.validationResults)) {
|
|
224
224
|
if (passed) score += 20;
|
|
225
225
|
else score -= 10;
|
|
226
226
|
}
|
|
@@ -440,7 +440,7 @@ class ProjectContextGenerator {
|
|
|
440
440
|
|
|
441
441
|
// Collect all array exports for global warning
|
|
442
442
|
const allArrayExports = [];
|
|
443
|
-
for (const [
|
|
443
|
+
for (const [_name, info] of Object.entries(exportMap.components)) {
|
|
444
444
|
if (info.arrayExports && info.arrayExports.length > 0) {
|
|
445
445
|
allArrayExports.push(...info.arrayExports);
|
|
446
446
|
}
|
|
@@ -479,7 +479,7 @@ class ProjectContextGenerator {
|
|
|
479
479
|
if (Object.keys(exportMap.services).length > 0) {
|
|
480
480
|
section += '### Services\n\n';
|
|
481
481
|
section += '```typescript\n';
|
|
482
|
-
for (const [
|
|
482
|
+
for (const [_name, info] of Object.entries(exportMap.services)) {
|
|
483
483
|
if (info.exports.length > 0) {
|
|
484
484
|
section += `import { ${info.exports.join(', ')} } from '${info.importPath}';\n`;
|
|
485
485
|
}
|
|
@@ -491,7 +491,7 @@ class ProjectContextGenerator {
|
|
|
491
491
|
if (Object.keys(exportMap.types).length > 0) {
|
|
492
492
|
section += '### Types\n\n';
|
|
493
493
|
section += '```typescript\n';
|
|
494
|
-
for (const [
|
|
494
|
+
for (const [_name, info] of Object.entries(exportMap.types)) {
|
|
495
495
|
if (info.types && info.types.length > 0) {
|
|
496
496
|
section += `import type { ${info.types.join(', ')} } from '${info.importPath}';\n`;
|
|
497
497
|
}
|
|
@@ -503,7 +503,7 @@ class ProjectContextGenerator {
|
|
|
503
503
|
if (Object.keys(exportMap.utils).length > 0) {
|
|
504
504
|
section += '### Utilities\n\n';
|
|
505
505
|
section += '```typescript\n';
|
|
506
|
-
for (const [
|
|
506
|
+
for (const [_name, info] of Object.entries(exportMap.utils)) {
|
|
507
507
|
if (info.exports.length > 0) {
|
|
508
508
|
section += `import { ${info.exports.join(', ')} } from '${info.importPath}';\n`;
|
|
509
509
|
}
|
|
@@ -34,17 +34,17 @@ const {
|
|
|
34
34
|
assessTaskComplexity,
|
|
35
35
|
TOKEN_BUDGETS: _TOKEN_BUDGETS,
|
|
36
36
|
getDefaultTokens,
|
|
37
|
-
|
|
37
|
+
_clampTokens
|
|
38
38
|
} = require('./flow-complexity');
|
|
39
39
|
|
|
40
40
|
// Import instruction richness module
|
|
41
41
|
const {
|
|
42
42
|
getInstructionRichness,
|
|
43
43
|
getVerbosityGuidance: _getVerbosityGuidance,
|
|
44
|
-
loadProjectContext:
|
|
44
|
+
loadProjectContext: _loadRichnessContext,
|
|
45
45
|
loadPatterns: _loadPatterns,
|
|
46
46
|
loadRelevantTypes: _loadRelevantTypes,
|
|
47
|
-
|
|
47
|
+
_loadRelatedCode
|
|
48
48
|
} = require('./flow-instruction-richness');
|
|
49
49
|
|
|
50
50
|
// Import export scanner module
|
|
@@ -67,7 +67,7 @@ const {
|
|
|
67
67
|
createExecutorFromConfig: _createExecutorFromConfig,
|
|
68
68
|
getExecutorConfig,
|
|
69
69
|
MODEL_CAPABILITIES: _MODEL_CAPABILITIES,
|
|
70
|
-
|
|
70
|
+
_getModelContextLimit
|
|
71
71
|
} = require('./flow-providers');
|
|
72
72
|
|
|
73
73
|
// Import response parser for error recovery
|
|
@@ -86,7 +86,7 @@ const {
|
|
|
86
86
|
analyzeFailure,
|
|
87
87
|
refinePromptForRetry,
|
|
88
88
|
recordSuccessfulRecovery,
|
|
89
|
-
|
|
89
|
+
_ERROR_CATEGORIES
|
|
90
90
|
} = require('./flow-adaptive-learning');
|
|
91
91
|
|
|
92
92
|
// Import pattern enforcer for active learning enforcement
|
|
@@ -94,7 +94,7 @@ const {
|
|
|
94
94
|
injectPatterns,
|
|
95
95
|
extractRelevantPatterns: _extractRelevantPatterns,
|
|
96
96
|
validateAgainstPatterns: _validateAgainstPatterns,
|
|
97
|
-
|
|
97
|
+
_generateSessionSummary
|
|
98
98
|
} = require('./flow-pattern-enforcer');
|
|
99
99
|
|
|
100
100
|
// v2.0: Import durable session for unified step tracking
|
|
@@ -109,12 +109,12 @@ const {
|
|
|
109
109
|
|
|
110
110
|
const {
|
|
111
111
|
classifyTask,
|
|
112
|
-
|
|
112
|
+
_getTaskTypeContext
|
|
113
113
|
} = require('./flow-task-classifier');
|
|
114
114
|
|
|
115
115
|
const {
|
|
116
116
|
learnFromFailure,
|
|
117
|
-
|
|
117
|
+
_enhancePromptWithLearning
|
|
118
118
|
} = require('./flow-failure-learning');
|
|
119
119
|
|
|
120
120
|
// ============================================================
|
|
@@ -342,7 +342,7 @@ function formatResults(comparison, results) {
|
|
|
342
342
|
// ============================================================
|
|
343
343
|
|
|
344
344
|
async function main() {
|
|
345
|
-
const { flags,
|
|
345
|
+
const { flags, _positional } = parseFlags(process.argv.slice(2));
|
|
346
346
|
|
|
347
347
|
if (flags.help) {
|
|
348
348
|
console.log(`
|
package/scripts/flow-phase.js
CHANGED
|
@@ -28,6 +28,15 @@ if (command === 'transition') {
|
|
|
28
28
|
const success = transitionPhase(from, to, taskId || null);
|
|
29
29
|
if (success) {
|
|
30
30
|
console.log(`Phase: ${from} → ${to}`);
|
|
31
|
+
// wf-8d635d0e / E1: fire background auto-review on coding → validating.
|
|
32
|
+
// Fails open — any error here must not fail the primary transition.
|
|
33
|
+
try {
|
|
34
|
+
const { maybeStartAutoReview } = require('./hooks/core/phase-transition-auto-review');
|
|
35
|
+
const result = maybeStartAutoReview(from, to, taskId || null);
|
|
36
|
+
if (result.started && process.env.DEBUG) {
|
|
37
|
+
console.error(`[auto-review] started pid=${result.handle?.pid} task=${taskId}`);
|
|
38
|
+
}
|
|
39
|
+
} catch (_err) { /* fail-open */ }
|
|
31
40
|
} else {
|
|
32
41
|
console.error(`Phase transition failed: ${from} → ${to}`);
|
|
33
42
|
process.exit(1);
|
|
@@ -78,7 +78,7 @@ function getProactiveCompactionConfig() {
|
|
|
78
78
|
* @returns {{ shouldCompact: boolean, reason: string, checkpoint: Object|null }}
|
|
79
79
|
*/
|
|
80
80
|
function shouldCompactAtPhase(params) {
|
|
81
|
-
const { phase, contextPercent,
|
|
81
|
+
const { phase, contextPercent, _taskId } = params;
|
|
82
82
|
const config = getProactiveCompactionConfig();
|
|
83
83
|
|
|
84
84
|
// Disabled — skip
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
const fs = require('node:fs');
|
|
18
18
|
const path = require('node:path');
|
|
19
|
+
const { DANGEROUS_KEYS } = require('./flow-io');
|
|
19
20
|
const {
|
|
20
21
|
PROJECT_ROOT,
|
|
21
22
|
parseFlags,
|
|
@@ -341,7 +342,7 @@ function applyTemplate(template, data) {
|
|
|
341
342
|
}
|
|
342
343
|
|
|
343
344
|
// Forbidden keys to prevent prototype pollution (case-insensitive)
|
|
344
|
-
|
|
345
|
+
// Consolidated to flow-io canonical (audit dup-002 / wf-9fc4970b).
|
|
345
346
|
|
|
346
347
|
// Simple substitution: {{key}} or {{object.key}}
|
|
347
348
|
return template.replace(/\{\{([^}]+)\}\}/g, (match, path) => {
|
|
@@ -351,7 +352,7 @@ function applyTemplate(template, data) {
|
|
|
351
352
|
for (const key of keys) {
|
|
352
353
|
// Prevent prototype pollution attacks (case-insensitive check)
|
|
353
354
|
const keyLower = key.toLowerCase();
|
|
354
|
-
if (
|
|
355
|
+
if (DANGEROUS_KEYS.has(keyLower)) return match;
|
|
355
356
|
if (value === undefined || value === null) return match;
|
|
356
357
|
// Only access own properties
|
|
357
358
|
if (!Object.hasOwn(value, key)) return match;
|
|
@@ -38,8 +38,9 @@ const MODEL_TEMPLATE_MAP = {
|
|
|
38
38
|
'gemini-2-flash': 'gemini-flash.yaml'
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
// Blocked keys for security (prototype pollution prevention)
|
|
42
|
-
|
|
41
|
+
// Blocked keys for security (prototype pollution prevention).
|
|
42
|
+
// Consolidated to flow-io canonical (audit dup-002 / wf-9fc4970b).
|
|
43
|
+
const { DANGEROUS_KEYS: BLOCKED_KEYS } = require('./flow-io');
|
|
43
44
|
|
|
44
45
|
// ============================================================
|
|
45
46
|
// YAML Parser (lightweight, no dependency)
|
|
@@ -203,7 +203,7 @@ class BaseProvider {
|
|
|
203
203
|
* Abstract — every concrete provider subclass (AnthropicProvider,
|
|
204
204
|
* OpenAIProvider, OllamaProvider, etc.) must override this.
|
|
205
205
|
*/
|
|
206
|
-
|
|
206
|
+
|
|
207
207
|
async complete(prompt, _options = {}) {
|
|
208
208
|
throw new Error(`Provider ${this.name}: complete() not implemented — override in subclass`);
|
|
209
209
|
}
|