moflo 4.9.20 → 4.9.22

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.
Files changed (240) hide show
  1. package/.claude/agents/analysis/analyze-code-quality.md +0 -121
  2. package/.claude/agents/analysis/code-analyzer.md +5 -26
  3. package/.claude/agents/architecture/system-design/arch-system-design.md +0 -119
  4. package/.claude/agents/base-template-generator.md +0 -1
  5. package/.claude/agents/core/coder.md +0 -22
  6. package/.claude/agents/core/planner.md +0 -16
  7. package/.claude/agents/core/researcher.md +0 -16
  8. package/.claude/agents/core/reviewer.md +0 -17
  9. package/.claude/agents/core/tester.md +0 -19
  10. package/.claude/agents/custom/test-long-runner.md +0 -2
  11. package/.claude/agents/development/dev-backend-api.md +0 -167
  12. package/.claude/agents/development/dev-database.md +43 -0
  13. package/.claude/agents/development/dev-frontend.md +42 -0
  14. package/.claude/agents/devops/ci-cd/ops-cicd-github.md +0 -112
  15. package/.claude/agents/documentation/api-docs/docs-api-openapi.md +0 -111
  16. package/.claude/agents/security/security-auditor.md +45 -0
  17. package/.claude/guidance/shipped/moflo-agent-rules.md +172 -0
  18. package/.claude/guidance/shipped/moflo-claude-swarm-cohesion.md +73 -265
  19. package/.claude/guidance/shipped/moflo-cli-reference.md +6 -6
  20. package/.claude/guidance/shipped/moflo-core-guidance.md +66 -184
  21. package/.claude/guidance/shipped/moflo-cross-platform.md +1 -1
  22. package/.claude/guidance/shipped/moflo-error-handling.md +3 -3
  23. package/.claude/guidance/shipped/moflo-guidance-rules.md +17 -7
  24. package/.claude/guidance/shipped/moflo-memory-strategy.md +76 -182
  25. package/.claude/guidance/shipped/moflo-memorydb-maintenance.md +6 -8
  26. package/.claude/guidance/shipped/moflo-settings-injection.md +7 -9
  27. package/.claude/guidance/shipped/moflo-source-hygiene.md +5 -5
  28. package/.claude/guidance/shipped/moflo-spell-connectors.md +3 -4
  29. package/.claude/guidance/shipped/moflo-spell-custom-steps.md +3 -4
  30. package/.claude/guidance/shipped/moflo-spell-engine.md +40 -162
  31. package/.claude/guidance/shipped/moflo-spell-runner.md +134 -0
  32. package/.claude/guidance/shipped/moflo-spell-sandboxing.md +10 -57
  33. package/.claude/guidance/shipped/moflo-spell-troubleshooting.md +149 -0
  34. package/.claude/guidance/shipped/moflo-subagents.md +43 -114
  35. package/.claude/guidance/shipped/moflo-task-icons.md +4 -4
  36. package/.claude/guidance/shipped/moflo-user-facing-language.md +3 -3
  37. package/.claude/guidance/shipped/moflo-verbose-command-filtering.md +3 -3
  38. package/.claude/guidance/shipped/moflo-yaml-reference.md +4 -5
  39. package/.claude/helpers/gate.cjs +192 -15
  40. package/.claude/helpers/prompt-hook.mjs +4 -38
  41. package/.claude/helpers/simplify-classify.cjs +32 -11
  42. package/.claude/helpers/subagent-bootstrap.json +1 -1
  43. package/.claude/helpers/subagent-start.cjs +1 -1
  44. package/.claude/skills/connector-builder/SKILL.md +42 -429
  45. package/.claude/skills/connector-builder/templates/connector.md +189 -0
  46. package/.claude/skills/connector-builder/templates/step-command.md +176 -0
  47. package/.claude/skills/eldar/SKILL.md +7 -7
  48. package/.claude/skills/fl/SKILL.md +3 -3
  49. package/.claude/skills/fl/execution-modes.md +39 -16
  50. package/.claude/skills/fl/phases.md +3 -3
  51. package/.claude/skills/{simplify → flo-simplify}/SKILL.md +11 -11
  52. package/.claude/skills/guidance/SKILL.md +17 -9
  53. package/.claude/skills/memory-patterns/SKILL.md +1 -1
  54. package/.claude/skills/publish/SKILL.md +121 -36
  55. package/.claude/skills/reset-epic/SKILL.md +2 -2
  56. package/.claude/skills/spell-builder/SKILL.md +39 -226
  57. package/.claude/skills/spell-builder/architecture.md +1 -1
  58. package/.claude/skills/spell-builder/permissions.md +107 -0
  59. package/.claude/skills/spell-builder/preflight.md +101 -0
  60. package/.claude/skills/spell-schedule/SKILL.md +2 -3
  61. package/bin/gate.cjs +192 -15
  62. package/bin/lib/retired-files.mjs +146 -0
  63. package/bin/prompt-hook.mjs +4 -38
  64. package/bin/session-start-launcher.mjs +120 -1
  65. package/bin/setup-project.mjs +63 -69
  66. package/bin/simplify-classify.cjs +32 -11
  67. package/dist/src/cli/appliance/rvfa-builder.js +1 -1
  68. package/dist/src/cli/commands/agent.js +3 -9
  69. package/dist/src/cli/commands/doctor-checks-deep.js +4 -0
  70. package/dist/src/cli/commands/hooks.js +1 -3
  71. package/dist/src/cli/commands/index.js +2 -0
  72. package/dist/src/cli/commands/retire.js +111 -0
  73. package/dist/src/cli/hooks/reasoningbank/index.js +7 -7
  74. package/dist/src/cli/init/claudemd-generator.js +30 -33
  75. package/dist/src/cli/init/executor.js +53 -69
  76. package/dist/src/cli/init/helpers-generator.js +165 -52
  77. package/dist/src/cli/init/moflo-init.js +41 -114
  78. package/dist/src/cli/init/settings-generator.js +44 -14
  79. package/dist/src/cli/mcp-tools/agent-tools.js +9 -27
  80. package/dist/src/cli/mcp-tools/hooks-tools.js +23 -21
  81. package/dist/src/cli/memory/controllers/semantic-router.js +18 -12
  82. package/dist/src/cli/memory/sona-optimizer.js +6 -6
  83. package/dist/src/cli/neural/domain/services/learning-service.js +3 -3
  84. package/dist/src/cli/services/agent-router.js +2 -5
  85. package/dist/src/cli/services/hook-block-hash.js +11 -2
  86. package/dist/src/cli/services/hook-wiring.js +86 -3
  87. package/dist/src/cli/services/subagent-bootstrap.js +1 -1
  88. package/dist/src/cli/shared/events/example-usage.js +6 -6
  89. package/dist/src/cli/shared/hooks/task-hooks.js +8 -8
  90. package/dist/src/cli/version.js +1 -1
  91. package/package.json +3 -2
  92. package/retired-files.json +1989 -0
  93. package/scripts/post-install-bootstrap.mjs +19 -0
  94. package/src/cli/data/model-registry.json +2 -2
  95. package/.claude/agents/consensus/byzantine-coordinator.md +0 -63
  96. package/.claude/agents/consensus/crdt-synchronizer.md +0 -997
  97. package/.claude/agents/consensus/gossip-coordinator.md +0 -63
  98. package/.claude/agents/consensus/performance-benchmarker.md +0 -851
  99. package/.claude/agents/consensus/quorum-manager.md +0 -823
  100. package/.claude/agents/consensus/raft-manager.md +0 -63
  101. package/.claude/agents/consensus/security-manager.md +0 -622
  102. package/.claude/agents/data/ml/data-ml-model.md +0 -193
  103. package/.claude/agents/github/code-review-swarm.md +0 -538
  104. package/.claude/agents/github/github-modes.md +0 -172
  105. package/.claude/agents/github/issue-tracker.md +0 -311
  106. package/.claude/agents/github/multi-repo-swarm.md +0 -551
  107. package/.claude/agents/github/pr-manager.md +0 -183
  108. package/.claude/agents/github/project-board-sync.md +0 -508
  109. package/.claude/agents/github/release-manager.md +0 -360
  110. package/.claude/agents/github/release-swarm.md +0 -580
  111. package/.claude/agents/github/repo-architect.md +0 -391
  112. package/.claude/agents/github/swarm-issue.md +0 -566
  113. package/.claude/agents/github/swarm-pr.md +0 -414
  114. package/.claude/agents/github/sync-coordinator.md +0 -426
  115. package/.claude/agents/github/workflow-automation.md +0 -606
  116. package/.claude/agents/goal/code-goal-planner.md +0 -440
  117. package/.claude/agents/goal/goal-planner.md +0 -168
  118. package/.claude/agents/hive-mind/collective-intelligence-coordinator.md +0 -127
  119. package/.claude/agents/hive-mind/queen-coordinator.md +0 -198
  120. package/.claude/agents/hive-mind/scout-explorer.md +0 -233
  121. package/.claude/agents/hive-mind/swarm-memory-manager.md +0 -184
  122. package/.claude/agents/hive-mind/worker-specialist.md +0 -208
  123. package/.claude/agents/neural/safla-neural.md +0 -73
  124. package/.claude/agents/optimization/benchmark-suite.md +0 -665
  125. package/.claude/agents/optimization/load-balancer.md +0 -431
  126. package/.claude/agents/optimization/performance-monitor.md +0 -672
  127. package/.claude/agents/optimization/resource-allocator.md +0 -674
  128. package/.claude/agents/optimization/topology-optimizer.md +0 -808
  129. package/.claude/agents/reasoning/goal-planner.md +0 -67
  130. package/.claude/agents/sona/sona-learning-optimizer.md +0 -74
  131. package/.claude/agents/sparc/architecture.md +0 -472
  132. package/.claude/agents/sparc/pseudocode.md +0 -318
  133. package/.claude/agents/sparc/refinement.md +0 -525
  134. package/.claude/agents/sparc/specification.md +0 -276
  135. package/.claude/agents/specialized/mobile/spec-mobile-react-native.md +0 -225
  136. package/.claude/agents/swarm/adaptive-coordinator.md +0 -391
  137. package/.claude/agents/swarm/hierarchical-coordinator.md +0 -321
  138. package/.claude/agents/swarm/mesh-coordinator.md +0 -383
  139. package/.claude/agents/testing/production-validator.md +0 -395
  140. package/.claude/agents/testing/tdd-london-swarm.md +0 -244
  141. package/.claude/agents/v3/adr-architect.md +0 -184
  142. package/.claude/agents/v3/aidefence-guardian.md +0 -277
  143. package/.claude/agents/v3/claims-authorizer.md +0 -208
  144. package/.claude/agents/v3/collective-intelligence-coordinator.md +0 -988
  145. package/.claude/agents/v3/ddd-domain-expert.md +0 -220
  146. package/.claude/agents/v3/injection-analyst.md +0 -232
  147. package/.claude/agents/v3/memory-specialist.md +0 -987
  148. package/.claude/agents/v3/performance-engineer.md +0 -1225
  149. package/.claude/agents/v3/pii-detector.md +0 -146
  150. package/.claude/agents/v3/reasoningbank-learner.md +0 -213
  151. package/.claude/agents/v3/security-architect-aidefence.md +0 -405
  152. package/.claude/agents/v3/security-architect.md +0 -865
  153. package/.claude/agents/v3/security-auditor.md +0 -771
  154. package/.claude/agents/v3/sparc-orchestrator.md +0 -182
  155. package/.claude/agents/v3/swarm-memory-manager.md +0 -142
  156. package/.claude/agents/v3/v3-integration-architect.md +0 -205
  157. package/.claude/commands/claude-flow-help.md +0 -103
  158. package/.claude/commands/claude-flow-memory.md +0 -107
  159. package/.claude/commands/claude-flow-swarm.md +0 -205
  160. package/.claude/commands/github/README.md +0 -11
  161. package/.claude/commands/github/code-review-swarm.md +0 -514
  162. package/.claude/commands/github/code-review.md +0 -25
  163. package/.claude/commands/github/github-modes.md +0 -146
  164. package/.claude/commands/github/github-swarm.md +0 -113
  165. package/.claude/commands/github/issue-tracker.md +0 -284
  166. package/.claude/commands/github/issue-triage.md +0 -25
  167. package/.claude/commands/github/multi-repo-swarm.md +0 -519
  168. package/.claude/commands/github/pr-enhance.md +0 -26
  169. package/.claude/commands/github/pr-manager.md +0 -164
  170. package/.claude/commands/github/project-board-sync.md +0 -471
  171. package/.claude/commands/github/release-manager.md +0 -332
  172. package/.claude/commands/github/release-swarm.md +0 -544
  173. package/.claude/commands/github/repo-analyze.md +0 -25
  174. package/.claude/commands/github/repo-architect.md +0 -361
  175. package/.claude/commands/github/swarm-issue.md +0 -482
  176. package/.claude/commands/github/swarm-pr.md +0 -285
  177. package/.claude/commands/github/sync-coordinator.md +0 -294
  178. package/.claude/commands/github/workflow-automation.md +0 -442
  179. package/.claude/commands/hooks/README.md +0 -11
  180. package/.claude/commands/hooks/overview.md +0 -58
  181. package/.claude/commands/hooks/post-edit.md +0 -117
  182. package/.claude/commands/hooks/post-task.md +0 -112
  183. package/.claude/commands/hooks/pre-edit.md +0 -113
  184. package/.claude/commands/hooks/pre-task.md +0 -111
  185. package/.claude/commands/hooks/session-end.md +0 -118
  186. package/.claude/commands/hooks/setup.md +0 -103
  187. package/.claude/commands/simplify.md +0 -101
  188. package/.claude/commands/sparc/analyzer.md +0 -42
  189. package/.claude/commands/sparc/architect.md +0 -43
  190. package/.claude/commands/sparc/ask.md +0 -86
  191. package/.claude/commands/sparc/batch-executor.md +0 -44
  192. package/.claude/commands/sparc/code.md +0 -78
  193. package/.claude/commands/sparc/coder.md +0 -44
  194. package/.claude/commands/sparc/debug.md +0 -72
  195. package/.claude/commands/sparc/debugger.md +0 -44
  196. package/.claude/commands/sparc/designer.md +0 -43
  197. package/.claude/commands/sparc/devops.md +0 -98
  198. package/.claude/commands/sparc/docs-writer.md +0 -69
  199. package/.claude/commands/sparc/documenter.md +0 -44
  200. package/.claude/commands/sparc/innovator.md +0 -44
  201. package/.claude/commands/sparc/integration.md +0 -72
  202. package/.claude/commands/sparc/mcp.md +0 -106
  203. package/.claude/commands/sparc/memory-manager.md +0 -44
  204. package/.claude/commands/sparc/optimizer.md +0 -44
  205. package/.claude/commands/sparc/orchestrator.md +0 -116
  206. package/.claude/commands/sparc/post-deployment-monitoring-mode.md +0 -72
  207. package/.claude/commands/sparc/refinement-optimization-mode.md +0 -72
  208. package/.claude/commands/sparc/researcher.md +0 -44
  209. package/.claude/commands/sparc/reviewer.md +0 -44
  210. package/.claude/commands/sparc/security-review.md +0 -69
  211. package/.claude/commands/sparc/sparc-modes.md +0 -139
  212. package/.claude/commands/sparc/sparc.md +0 -99
  213. package/.claude/commands/sparc/spec-pseudocode.md +0 -69
  214. package/.claude/commands/sparc/spell-manager.md +0 -44
  215. package/.claude/commands/sparc/supabase-admin.md +0 -337
  216. package/.claude/commands/sparc/swarm-coordinator.md +0 -44
  217. package/.claude/commands/sparc/tdd.md +0 -44
  218. package/.claude/commands/sparc/tester.md +0 -44
  219. package/.claude/commands/sparc/tutorial.md +0 -68
  220. package/.claude/commands/sparc.md +0 -151
  221. package/.claude/guidance/shipped/moflo-session-start.md +0 -154
  222. package/.claude/guidance/shipped/moflo-spell-engine-architecture.md +0 -145
  223. package/.claude/skills/browser/SKILL.md +0 -204
  224. package/.claude/skills/github-code-review/SKILL.md +0 -1140
  225. package/.claude/skills/github-multi-repo/SKILL.md +0 -866
  226. package/.claude/skills/github-project-management/SKILL.md +0 -1272
  227. package/.claude/skills/github-release-management/SKILL.md +0 -1074
  228. package/.claude/skills/github-workflow-automation/SKILL.md +0 -1060
  229. package/.claude/skills/hive-mind-advanced/SKILL.md +0 -712
  230. package/.claude/skills/hooks-automation/SKILL.md +0 -1193
  231. package/.claude/skills/pair-programming/SKILL.md +0 -1202
  232. package/.claude/skills/performance-analysis/SKILL.md +0 -563
  233. package/.claude/skills/skill-builder/SKILL.md +0 -910
  234. package/.claude/skills/sparc-methodology/SKILL.md +0 -904
  235. package/.claude/skills/stream-chain/SKILL.md +0 -563
  236. package/.claude/skills/swarm-advanced/SKILL.md +0 -811
  237. package/.claude/skills/swarm-orchestration/SKILL.md +0 -179
  238. package/.claude/skills/verification-quality/SKILL.md +0 -649
  239. package/.claude/skills/worker-benchmarks/skill.md +0 -135
  240. package/.claude/skills/worker-integration/skill.md +0 -154
@@ -7,7 +7,7 @@ var cp = require('child_process');
7
7
  var PROJECT_DIR = (process.env.CLAUDE_PROJECT_DIR || process.cwd()).replace(/^\/([a-z])\//i, '$1:/');
8
8
  var STATE_FILE = path.join(PROJECT_DIR, '.claude', 'workflow-state.json');
9
9
 
10
- var STATE_DEFAULTS = { tasksCreated: false, taskCount: 0, memorySearched: false, memorySearchedBy: {}, memoryRequired: true, learningsStored: false, testsRun: false, simplifyRun: false, simplifySnapshotSha: null, interactionCount: 0, sessionStart: null, lastBlockedAt: null };
10
+ var STATE_DEFAULTS = { tasksCreated: false, taskCount: 0, memorySearched: false, memorySearchedBy: {}, memoryRequired: true, learningsStored: false, testsRun: false, simplifyRun: false, simplifySnapshotSha: null, interactionCount: 0, sessionStart: null, lastBlockedAt: null, lastNamespaceHint: '', lastNamespaceHintEmittedBy: {}, flMode: null, swarmInitialized: false, hiveInitialized: false };
11
11
 
12
12
  // Per-actor memory-search tracking (#838). The legacy `memorySearched` boolean
13
13
  // is session-wide, so once the parent searches memory, every spawned subagent
@@ -60,7 +60,7 @@ function writeState(s) {
60
60
 
61
61
  // Load moflo.yaml gate config (defaults: all enabled)
62
62
  function loadGateConfig() {
63
- var defaults = { memory_first: true, task_create_first: true, context_tracking: true, testing_gate: true, simplify_gate: true, learnings_gate: true };
63
+ var defaults = { memory_first: true, task_create_first: true, context_tracking: true, testing_gate: true, simplify_gate: true, learnings_gate: true, swarm_invocation_gate: true };
64
64
  try {
65
65
  var yamlPath = path.join(PROJECT_DIR, 'moflo.yaml');
66
66
  if (fs.existsSync(yamlPath)) {
@@ -71,6 +71,7 @@ function loadGateConfig() {
71
71
  if (/testing_gate:\s*false/i.test(content)) defaults.testing_gate = false;
72
72
  if (/simplify_gate:\s*false/i.test(content)) defaults.simplify_gate = false;
73
73
  if (/learnings_gate:\s*false/i.test(content)) defaults.learnings_gate = false;
74
+ if (/swarm_invocation_gate:\s*false/i.test(content)) defaults.swarm_invocation_gate = false;
74
75
  }
75
76
  } catch (e) { /* use defaults */ }
76
77
  return defaults;
@@ -83,6 +84,99 @@ var EXEMPT = ['.claude/', '.claude\\', 'CLAUDE.md', 'MEMORY.md', 'workflow-state
83
84
  var DANGEROUS = ['rm -rf /', 'format c:', 'del /s /q c:\\', ':(){:|:&};:', 'mkfs.', '> /dev/sda'];
84
85
  var DIRECTIVE_RE = /^(yes|no|yeah|yep|nope|sure|ok|okay|correct|right|exactly|perfect)\b/i;
85
86
  var TASK_RE = /\b(fix|bug|error|implement|add|create|build|write|refactor|debug|test|feature|issue|security|optimi)\b/i;
87
+
88
+ // Namespace classification (#931). The hint used to be emitted on every prompt
89
+ // by prompt-hook.mjs which cost ~40 tokens × every prompt × every consumer.
90
+ // Now we classify here, store on workflow-state, and let check-before-agent
91
+ // emit it once when Claude is actually about to spawn an agent.
92
+ //
93
+ // SYNC: these regexes + classifyNamespaceHint + applyPromptStateReset are
94
+ // duplicated verbatim in src/cli/init/helpers-generator.ts (the embedded
95
+ // gate.cjs fallback used by `flo init` when source helpers can't be located).
96
+ // Any edit to either copy MUST be applied to both — there is no shared module
97
+ // because helpers-generator emits a self-contained string template.
98
+ var NS_LEARNINGS_RE = /\b(remember|recall|insight|lesson learned|gotcha|post.?mortem)\b|we (decid|agree|chose|said)/;
99
+ var NS_TEST_RE = /\b(test|spec|coverage|tested|test case|test cases|tests for|spec for)\b/;
100
+ var NS_EXPLICIT = [
101
+ { pattern: /\b(pattern|convention|best practice|style|coding rule)\b/, ns: 'patterns', label: 'code patterns and conventions' },
102
+ { pattern: /\b(code.?map|file structure|project structure|directory)\b/, ns: 'code-map', label: 'codebase navigation' },
103
+ ];
104
+ var NS_PATTERN_RES = [/\b(template|example|similar to|how do we|how should)\b/];
105
+ var NS_DOMAIN_RES = [
106
+ /\b(guidance|guide|docs|documentation|rules|how-to)\b/,
107
+ /\b(architecture|design|domain|tenant|migrat|schema|deploy)/,
108
+ /\b(rule|requirement|constraint|compliance)\b/,
109
+ ];
110
+ var NS_NAV_RES = [
111
+ /\b(find|where|which file|look up|locate|endpoint|route|url|path)\b/,
112
+ /\b(class|function|method|component|service|entity|module)\b/,
113
+ ];
114
+
115
+ // Detect whether the current prompt invoked /fl or /flo with a swarm/hive flag (#952).
116
+ // When set, check-before-agent BLOCKS the Agent spawn until the matching MCP init
117
+ // (mcp__moflo__swarm_init or mcp__moflo__hive-mind_init) has been recorded — the user
118
+ // explicitly opted in to the protected coordination surface, so falling back to
119
+ // raw Agent dispatch silently regresses headline moflo product capability.
120
+ //
121
+ // SYNC: duplicated verbatim in src/cli/init/helpers-generator.ts.
122
+ function detectFlMode(promptText) {
123
+ var p = promptText || '';
124
+ if (!/^\s*\/(?:fl|flo)\b/i.test(p)) return null;
125
+ if (/(?:^|\s)(?:-s|--swarm)\b/.test(p)) return 'swarm';
126
+ if (/(?:^|\s)(?:-h|--hive)\b/.test(p)) return 'hive';
127
+ return null;
128
+ }
129
+
130
+ function classifyNamespaceHint(promptText) {
131
+ var lower = (promptText || '').toLowerCase();
132
+ if (NS_TEST_RE.test(lower)) return 'Memory namespace hint: use "tests" for test inventory and coverage lookups.';
133
+ if (NS_LEARNINGS_RE.test(lower)) return 'Memory namespace hint: use "learnings" for user-directed decisions and distilled insights.';
134
+ for (var i = 0; i < NS_EXPLICIT.length; i++) {
135
+ if (NS_EXPLICIT[i].pattern.test(lower)) return 'Memory namespace hint: use "' + NS_EXPLICIT[i].ns + '" for ' + NS_EXPLICIT[i].label + '.';
136
+ }
137
+ for (var j = 0; j < NS_DOMAIN_RES.length; j++) {
138
+ if (NS_DOMAIN_RES[j].test(lower)) return 'Memory namespace hint: search "guidance" and "learnings" for domain rules and project decisions.';
139
+ }
140
+ for (var k = 0; k < NS_PATTERN_RES.length; k++) {
141
+ if (NS_PATTERN_RES[k].test(lower)) return 'Memory namespace hint: use "patterns" for code patterns and conventions.';
142
+ }
143
+ for (var m = 0; m < NS_NAV_RES.length; m++) {
144
+ if (NS_NAV_RES[m].test(lower)) return 'Memory namespace hint: use "code-map" for codebase navigation.';
145
+ }
146
+ return '';
147
+ }
148
+
149
+ // Apply per-prompt state reset shared by `prompt-reminder` (full) and
150
+ // `prompt-state-reset` (defensive safety-net, no emission). Idempotent — both
151
+ // UserPromptSubmit hooks can run it without compounding any field. Caller
152
+ // owns interactionCount and the user-visible REMINDER/Context emissions, so
153
+ // this helper stays silent.
154
+ function applyPromptStateReset(state, promptText) {
155
+ state.memorySearched = false;
156
+ // Wipe per-actor memory tracking too — a new user prompt is a fresh window
157
+ // for both parent AND any subagents the parent may spawn during this turn.
158
+ state.memorySearchedBy = {};
159
+ // learningsStored is session-scoped — once stored, it stays true until session reset.
160
+ // Resetting per-prompt caused false blocks when PR creation was on a later prompt.
161
+ var DIRECTIVE_MAX_LEN = 20;
162
+ var escaped = /^@@\s*/.test(promptText || '');
163
+ state.memoryRequired = !escaped && (promptText || '').length >= 4 && (TASK_RE.test(promptText || '') || (promptText || '').length > DIRECTIVE_MAX_LEN);
164
+ // Stash namespace hint for check-before-agent to emit when Claude actually
165
+ // spawns an Agent (#931). Empty string when nothing matched — overwriting
166
+ // any stale value from the previous prompt.
167
+ state.lastNamespaceHint = classifyNamespaceHint(promptText);
168
+ // Per-actor emission tracking — each subagent's session gets the hint at
169
+ // most once per prompt, but a fresh prompt resets every actor's window so
170
+ // subsequent agents (parent + subagents that spawn their own agents) all
171
+ // see the new classification on their first check-before-agent.
172
+ state.lastNamespaceHintEmittedBy = {};
173
+ // #952 — derive flMode from the user prompt, and reset the matching init
174
+ // flag. Each /fl invocation must call its protected MCP init; the previous
175
+ // prompt's swarm/hive registration does not satisfy this prompt's gate.
176
+ state.flMode = detectFlMode(promptText);
177
+ state.swarmInitialized = false;
178
+ state.hiveInitialized = false;
179
+ }
86
180
  // Match npm/yarn/pnpm/bun test, npx vitest|jest|..., bare runners at command-start only,
87
181
  // and language-native test commands. The bare-runner arm is anchored so that
88
182
  // `npm install jest`, `grep -r vitest src/`, and similar don't false-positive.
@@ -203,6 +297,11 @@ switch (command) {
203
297
  // Advisory only — agent spawning is never blocked.
204
298
  // Memory-first enforcement happens at the scan/read gate layer.
205
299
  // SubagentStart hook injects guidance directive into subagent context.
300
+ //
301
+ // #931 — TaskCreate REMINDER and the namespace hint moved here from
302
+ // prompt-reminder. They only matter when Claude is actually about to spawn
303
+ // an Agent; emitting per-prompt cost ~90 tokens × every prompt × every
304
+ // consumer.
206
305
  var s = readState();
207
306
  if (config.task_create_first && !s.tasksCreated) {
208
307
  process.stdout.write('REMINDER: Use TaskCreate before spawning agents. Task tool is blocked until then.\n');
@@ -210,6 +309,65 @@ switch (command) {
210
309
  if (config.memory_first && s.memoryRequired && !s.memorySearched) {
211
310
  process.stdout.write('REMINDER: Search memory (mcp__moflo__memory_search) before spawning agents.\n');
212
311
  }
312
+ if (s.lastNamespaceHint) {
313
+ // Per-actor single-shot. Each session_id gets the hint at most once per
314
+ // prompt, but the hint itself stays available for other actors (e.g.
315
+ // a subagent that spawns its own agent has its own session_id and is
316
+ // entitled to a fresh emission). Falls back to a `_legacy_` bucket when
317
+ // Claude Code didn't forward a session_id (older host or direct CLI
318
+ // invocation), preserving the old "emit once globally" behavior. The
319
+ // map is wiped by applyPromptStateReset on every new prompt.
320
+ var sid = process.env.HOOK_SESSION_ID || '';
321
+ var emittedBy = s.lastNamespaceHintEmittedBy || {};
322
+ var bucket = sid || '_legacy_';
323
+ if (!emittedBy[bucket]) {
324
+ process.stdout.write(s.lastNamespaceHint + '\n');
325
+ emittedBy[bucket] = true;
326
+ s.lastNamespaceHintEmittedBy = emittedBy;
327
+ writeState(s);
328
+ }
329
+ }
330
+ // #952 — when /fl was invoked with -s/-h, the protected MCP init must run
331
+ // BEFORE any Agent spawn. Hard block: the user explicitly opted in to
332
+ // moflo's coordination surface, so silently dispatching `Agent` calls
333
+ // without `mcp__moflo__swarm_init` / `mcp__moflo__hive-mind_init` is the
334
+ // failure mode this gate exists to prevent (CLAUDE.md "⛔ Protected
335
+ // functionality — swarm + hive-mind"). Other Agent uses remain advisory.
336
+ if (config.swarm_invocation_gate) {
337
+ if (s.flMode === 'swarm' && !s.swarmInitialized) {
338
+ process.stderr.write('BLOCKED: /fl was invoked with -s/--swarm but mcp__moflo__swarm_init has not been called.\n');
339
+ process.stderr.write('Run mcp__moflo__swarm_init first, then mcp__moflo__agent_spawn for each role, then dispatch Agent.\n');
340
+ process.stderr.write('See .claude/skills/fl/execution-modes.md "SWARM mode" and CLAUDE.md "⛔ Protected functionality".\n');
341
+ process.stderr.write('Disable via moflo.yaml: gates: swarm_invocation_gate: false\n');
342
+ process.exit(2);
343
+ }
344
+ if (s.flMode === 'hive' && !s.hiveInitialized) {
345
+ process.stderr.write('BLOCKED: /fl was invoked with -h/--hive but mcp__moflo__hive-mind_init has not been called.\n');
346
+ process.stderr.write('Run mcp__moflo__hive-mind_init first, then dispatch Agent or hive-mind workers.\n');
347
+ process.stderr.write('See .claude/skills/fl/execution-modes.md "HIVE-MIND mode" and CLAUDE.md "⛔ Protected functionality".\n');
348
+ process.stderr.write('Disable via moflo.yaml: gates: swarm_invocation_gate: false\n');
349
+ process.exit(2);
350
+ }
351
+ }
352
+ break;
353
+ }
354
+ case 'record-swarm-init': {
355
+ // #952 — wired to mcp__moflo__swarm_init PostToolUse. Marks the gate
356
+ // satisfied so subsequent Agent spawns under /fl -s pass.
357
+ var s = readState();
358
+ if (!s.swarmInitialized) {
359
+ s.swarmInitialized = true;
360
+ writeState(s);
361
+ }
362
+ break;
363
+ }
364
+ case 'record-hive-init': {
365
+ // #952 — wired to mcp__moflo__hive-mind_init PostToolUse.
366
+ var s = readState();
367
+ if (!s.hiveInitialized) {
368
+ s.hiveInitialized = true;
369
+ writeState(s);
370
+ }
213
371
  break;
214
372
  }
215
373
  case 'check-before-scan': {
@@ -277,7 +435,8 @@ switch (command) {
277
435
  break;
278
436
  }
279
437
  case 'record-skill-run': {
280
- if ((process.env.TOOL_INPUT_skill || '') === 'simplify') {
438
+ var skName = (process.env.TOOL_INPUT_skill || '');
439
+ if (skName === 'simplify' || skName === 'flo-simplify') {
281
440
  var s = readState();
282
441
  var changed = false;
283
442
  if (!s.simplifyRun) { s.simplifyRun = true; changed = true; }
@@ -346,7 +505,7 @@ switch (command) {
346
505
  }
347
506
  var missing = [];
348
507
  if (config.testing_gate && !s.testsRun) missing.push('tests have not run since the last code edit (run npm test, vitest, jest, pytest, or similar)');
349
- if (config.simplify_gate && !s.simplifyRun) missing.push('/simplify has not run since the last code edit');
508
+ if (config.simplify_gate && !s.simplifyRun) missing.push('/flo-simplify has not run since the last code edit');
350
509
  if (config.learnings_gate && !s.learningsStored) missing.push('learnings have not been stored (call mcp__moflo__memory_store)');
351
510
  if (missing.length === 0) break;
352
511
  process.stderr.write('BLOCKED: gh pr create requires the following before opening a PR:\n');
@@ -371,20 +530,16 @@ switch (command) {
371
530
  break;
372
531
  }
373
532
  case 'prompt-reminder': {
533
+ // Full per-prompt reset. Wired as the first UserPromptSubmit hook (via
534
+ // prompt-hook.mjs). Owns interactionCount + Context warnings; the
535
+ // TaskCreate REMINDER and namespace hint moved to check-before-agent
536
+ // (#931) so they only fire when Claude is actually about to spawn an
537
+ // Agent.
374
538
  var s = readState();
375
- s.memorySearched = false;
376
- // Wipe per-actor memory tracking too — a new user prompt is a fresh window
377
- // for both parent AND any subagents the parent may spawn during this turn.
378
- s.memorySearchedBy = {};
379
- // learningsStored is session-scoped — once stored, it stays true until session reset.
380
- // Resetting per-prompt caused false blocks when PR creation was on a later prompt.
381
539
  var prompt = process.env.CLAUDE_USER_PROMPT || '';
382
- var DIRECTIVE_MAX_LEN = 20;
383
- var escaped = /^@@\s*/.test(prompt);
384
- s.memoryRequired = !escaped && prompt.length >= 4 && (TASK_RE.test(prompt) || prompt.length > DIRECTIVE_MAX_LEN);
540
+ applyPromptStateReset(s, prompt);
385
541
  s.interactionCount = (s.interactionCount || 0) + 1;
386
542
  writeState(s);
387
- if (!s.tasksCreated) console.log('REMINDER: Use TaskCreate before spawning agents. Task tool is blocked until then.');
388
543
  if (config.context_tracking) {
389
544
  var ic = s.interactionCount;
390
545
  if (ic > 30) console.log('Context: CRITICAL. Commit, store learnings, suggest new session.');
@@ -393,12 +548,34 @@ switch (command) {
393
548
  }
394
549
  break;
395
550
  }
551
+ case 'prompt-state-reset': {
552
+ // Defensive safety-net hook (#931 dedupe). Wired as the second
553
+ // UserPromptSubmit hook so an exception in prompt-hook.mjs doesn't skip
554
+ // the per-prompt state reset. Idempotent — applyPromptStateReset only
555
+ // sets fields to derived values, and we deliberately do NOT increment
556
+ // interactionCount or emit anything (that's prompt-reminder's job).
557
+ //
558
+ // Skip the disk write on the normal path: prompt-reminder runs first and
559
+ // already wrote the byte-identical post-reset state. Only writeState when
560
+ // the reset actually changed something (i.e., prompt-reminder was skipped
561
+ // because prompt-hook.mjs threw before invoking it).
562
+ var s = readState();
563
+ var prompt = process.env.CLAUDE_USER_PROMPT || '';
564
+ var before = JSON.stringify(s);
565
+ applyPromptStateReset(s, prompt);
566
+ if (JSON.stringify(s) !== before) writeState(s);
567
+ break;
568
+ }
396
569
  case 'compact-guidance': {
397
570
  console.log('Pre-Compact: Check CLAUDE.md for rules. Use memory search to recover context after compact.');
398
571
  break;
399
572
  }
400
573
  case 'session-reset': {
401
- writeState({ tasksCreated: false, taskCount: 0, memorySearched: false, memorySearchedBy: {}, memoryRequired: true, learningsStored: false, testsRun: false, simplifyRun: false, interactionCount: 0, sessionStart: new Date().toISOString(), lastBlockedAt: null });
574
+ // Derive from STATE_DEFAULTS so adding a new state field requires only one
575
+ // edit (the defaults object) — the literal that used to live here drifted
576
+ // every time a field was added and is what motivated #952's audit of state
577
+ // shape consistency.
578
+ writeState(Object.assign({}, STATE_DEFAULTS, { sessionStart: new Date().toISOString() }));
402
579
  break;
403
580
  }
404
581
  default:
@@ -33,43 +33,9 @@ try {
33
33
  });
34
34
  } catch (err) { output = (err && err.stdout) || ''; }
35
35
 
36
- // Classify prompt for namespace hint
37
- var lower = userPrompt.toLowerCase();
38
-
39
- var LEARNINGS_HINTS = /\b(remember|recall|insight|lesson learned|gotcha|post.?mortem)\b|we (decid|agree|chose|said)/;
40
- var TEST_HINTS = /\b(test|spec|coverage|tested|test case|test cases|tests for|spec for)\b/;
41
- var EXPLICIT_NS = [
42
- { pattern: /\b(pattern|convention|best practice|style|coding rule)\b/, ns: 'patterns', label: 'code patterns and conventions' },
43
- { pattern: /\b(code.?map|file structure|project structure|directory)\b/, ns: 'code-map', label: 'codebase navigation' },
44
- ];
45
- var PATTERN_HINTS = [/\b(template|example|similar to|how do we|how should)\b/];
46
- var DOMAIN_HINTS = [
47
- /\b(guidance|guide|docs|documentation|rules|how-to)\b/,
48
- /\b(architecture|design|domain|tenant|migrat|schema|deploy)/,
49
- /\b(rule|requirement|constraint|compliance)\b/,
50
- ];
51
- var NAV_PATTERNS = [
52
- /\b(find|where|which file|look up|locate|endpoint|route|url|path)\b/,
53
- /\b(class|function|method|component|service|entity|module)\b/,
54
- ];
55
-
56
- var nsHint = '';
57
- if (TEST_HINTS.test(lower)) {
58
- nsHint = 'Memory namespace hint: use "tests" for test inventory and coverage lookups.';
59
- } else if (LEARNINGS_HINTS.test(lower)) {
60
- nsHint = 'Memory namespace hint: use "learnings" for user-directed decisions and distilled insights.';
61
- } else {
62
- var found = EXPLICIT_NS.find(function(e) { return e.pattern.test(lower); });
63
- if (found) {
64
- nsHint = 'Memory namespace hint: use "' + found.ns + '" for ' + found.label + '.';
65
- } else if (DOMAIN_HINTS.some(function(p) { return p.test(lower); })) {
66
- nsHint = 'Memory namespace hint: search "guidance" and "learnings" for domain rules and project decisions.';
67
- } else if (PATTERN_HINTS.some(function(p) { return p.test(lower); })) {
68
- nsHint = 'Memory namespace hint: use "patterns" for code patterns and conventions.';
69
- } else if (NAV_PATTERNS.some(function(p) { return p.test(lower); })) {
70
- nsHint = 'Memory namespace hint: use "code-map" for codebase navigation.';
71
- }
72
- }
36
+ // #931 Namespace hint classification moved into gate.cjs (computed by
37
+ // prompt-reminder, stored on workflow-state.json, emitted once by
38
+ // check-before-agent at Agent-spawn time). No per-prompt token leak now.
73
39
 
74
40
  // #867 — surface post-install restart notice. File is written by
75
41
  // scripts/post-install-notice.mjs and cleared by the SessionStart launcher
@@ -84,6 +50,6 @@ try {
84
50
  }
85
51
  } catch (e) { /* ENOENT or malformed — silent fast-path */ }
86
52
 
87
- var parts = [restartNotice, output.trim(), nsHint].filter(Boolean);
53
+ var parts = [restartNotice, output.trim()].filter(Boolean);
88
54
  if (parts.length) process.stdout.write(parts.join('\n\n') + '\n');
89
55
  process.exit(0);
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * /simplify diff classifier — issue #908.
3
+ * /flo-simplify diff classifier.
4
4
  *
5
5
  * Decides which review tier the current diff warrants and returns a JSON
6
- * dispatch decision. The /simplify skill MUST call this first so routing is
6
+ * dispatch decision. The /flo-simplify skill MUST call this first so routing is
7
7
  * deterministic and unit-testable instead of a prose decision Claude makes
8
8
  * over and over per run.
9
9
  *
10
- * Rule (per user direction): default to single-agent Sonnet review. Only
11
- * escalate to a 3-agent fan-out when diff signals genuinely warrant it.
12
- * Opus is never selected — the existing skill already documents that.
10
+ * Rule: default to single-agent Sonnet review. Only escalate to a 3-agent
11
+ * fan-out when diff signals genuinely warrant it. Opus is never selected —
12
+ * the existing skill already documents that.
13
13
  *
14
14
  * Outputs JSON:
15
15
  * {
@@ -21,7 +21,8 @@
21
21
  * }
22
22
  *
23
23
  * Usage:
24
- * node bin/simplify-classify.cjs [--base main]
24
+ * node bin/simplify-classify.cjs # auto-detects default branch
25
+ * node bin/simplify-classify.cjs --base develop # explicit override
25
26
  * node bin/simplify-classify.cjs --diff <unified-diff-on-stdin>
26
27
  *
27
28
  * The --diff stdin form exists so unit tests can drive the classifier
@@ -31,7 +32,7 @@
31
32
 
32
33
  const { execSync } = require('child_process');
33
34
 
34
- // Paths where new logic warrants the 3-agent fan-out (issue #908).
35
+ // Paths where new logic warrants the 3-agent fan-out.
35
36
  // Mechanical edits inside these paths are still SMALL; only adding/removing
36
37
  // declarations triggers escalation.
37
38
  const SECURITY_PATHS = [
@@ -49,6 +50,25 @@ function safeExec(cmd) {
49
50
  catch { return ''; }
50
51
  }
51
52
 
53
+ // Detect the consumer's default branch. Hardcoding 'main' silently miscalibrates
54
+ // classification on repos that use 'master', 'develop', etc. — empty diff →
55
+ // TRIVIAL → gate stamps clean without any real review.
56
+ let _cachedDefaultBranch = null;
57
+ function detectDefaultBranch() {
58
+ if (_cachedDefaultBranch !== null) return _cachedDefaultBranch;
59
+
60
+ // Preferred: origin/HEAD points to whatever the remote considers default.
61
+ const symbolic = safeExec('git symbolic-ref --short refs/remotes/origin/HEAD').trim();
62
+ if (symbolic.startsWith('origin/')) return (_cachedDefaultBranch = symbolic.slice('origin/'.length));
63
+
64
+ // Fallback: local init.defaultBranch (set by `git init -b <name>` or config).
65
+ const configured = safeExec('git config --get init.defaultBranch').trim();
66
+ if (configured) return (_cachedDefaultBranch = configured);
67
+
68
+ // Last resort: 'main' (most common modern default).
69
+ return (_cachedDefaultBranch = 'main');
70
+ }
71
+
52
72
  function readDiffFromGit(base) {
53
73
  // Combined diff: committed-since-base + working-tree
54
74
  const committed = safeExec(`git diff ${base}...HEAD`);
@@ -186,14 +206,15 @@ function classifyDiff(diffText) {
186
206
  return decide(parseDiff(diffText));
187
207
  }
188
208
 
189
- function classifyFromGit(base = 'main') {
190
- return classifyDiff(readDiffFromGit(base));
209
+ function classifyFromGit(base) {
210
+ const resolved = base || detectDefaultBranch();
211
+ return classifyDiff(readDiffFromGit(resolved));
191
212
  }
192
213
 
193
214
  if (require.main === module) {
194
215
  const args = process.argv.slice(2);
195
216
  const baseIdx = args.indexOf('--base');
196
- const base = baseIdx >= 0 ? args[baseIdx + 1] : 'main';
217
+ const base = baseIdx >= 0 ? args[baseIdx + 1] : detectDefaultBranch();
197
218
  const stdinDiff = args.includes('--diff') || args.includes('--stdin');
198
219
 
199
220
  let result;
@@ -211,4 +232,4 @@ if (require.main === module) {
211
232
  }
212
233
  }
213
234
 
214
- module.exports = { parseDiff, decide, classifyDiff, classifyFromGit };
235
+ module.exports = { parseDiff, decide, classifyDiff, classifyFromGit, detectDefaultBranch };
@@ -1,3 +1,3 @@
1
1
  {
2
- "directive": "MANDATORY FIRST ACTION: Your very first tool call MUST be mcp__moflo__memory_search (any query, any namespace). The memory-first gate WILL BLOCK all Glob, Grep, and Read calls until you do this. After memory search, follow `.claude/guidance/shipped/moflo-subagents.md` protocol."
2
+ "directive": "MANDATORY FIRST ACTION: Your very first tool call MUST be mcp__moflo__memory_search (any query, any namespace). The memory-first gate WILL BLOCK all Glob, Grep, and Read calls until you do this. After memory search, follow `.claude/guidance/moflo-subagents.md` protocol."
3
3
  }
@@ -22,7 +22,7 @@ const path = require('path');
22
22
  // Defense-in-depth copy of the canonical directive in subagent-bootstrap.json.
23
23
  // Kept as a single-line literal so the parity test in tests/bin/subagent-start.test.ts
24
24
  // can verify it matches the JSON via plain substring containment.
25
- const FALLBACK_DIRECTIVE = 'MANDATORY FIRST ACTION: Your very first tool call MUST be mcp__moflo__memory_search (any query, any namespace). The memory-first gate WILL BLOCK all Glob, Grep, and Read calls until you do this. After memory search, follow `.claude/guidance/shipped/moflo-subagents.md` protocol.';
25
+ const FALLBACK_DIRECTIVE = 'MANDATORY FIRST ACTION: Your very first tool call MUST be mcp__moflo__memory_search (any query, any namespace). The memory-first gate WILL BLOCK all Glob, Grep, and Read calls until you do this. After memory search, follow `.claude/guidance/moflo-subagents.md` protocol.';
26
26
 
27
27
  function loadDirective() {
28
28
  const jsonPath = path.join(__dirname, 'subagent-bootstrap.json');