moflo 4.12.4 → 4.12.6
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/guidance/shipped/moflo-agent-rules.md +1 -0
- package/.claude/guidance/shipped/moflo-claude-swarm-cohesion.md +1 -1
- package/.claude/guidance/shipped/moflo-cli-reference.md +4 -4
- package/.claude/guidance/shipped/moflo-core-guidance.md +4 -4
- package/.claude/guidance/shipped/moflo-guidance-rules.md +21 -0
- package/.claude/guidance/shipped/moflo-inline-fixes.md +98 -0
- package/.claude/guidance/shipped/moflo-root-cause-discipline.md +10 -10
- package/.claude/guidance/shipped/moflo-sdd.md +5 -5
- package/.claude/guidance/shipped/moflo-spell-engine.md +1 -1
- package/.claude/guidance/shipped/moflo-yaml-reference.md +8 -8
- package/.claude/helpers/gate.cjs +46 -7
- package/.claude/helpers/pr-create-command.cjs +440 -0
- package/.claude/skills/eldar/SKILL.md +1 -1
- package/.claude/skills/fl/SKILL.md +6 -6
- package/.claude/skills/fl/execution-modes.md +3 -3
- package/.claude/skills/fl/phases.md +8 -8
- package/.claude/skills/fl/sdd.md +6 -6
- package/.claude/skills/guidance/SKILL.md +3 -0
- package/.claude/skills/verify/SKILL.md +4 -4
- package/bin/gate.cjs +46 -7
- package/bin/hooks.mjs +4 -1
- package/bin/lib/retired-files.mjs +38 -6
- package/bin/lib/shipped-scripts.json +2 -1
- package/bin/lib/skill-categories.mjs +81 -17
- package/bin/pr-create-command.cjs +440 -0
- package/bin/session-start-launcher.mjs +11 -6
- package/dist/src/cli/aidefence/domain/entities/threat.js +2 -1
- package/dist/src/cli/commands/doctor-checks-deep.js +3 -2
- package/dist/src/cli/commands/doctor-checks-memory-access.js +3 -2
- package/dist/src/cli/commands/doctor-checks-swarm.js +3 -2
- package/dist/src/cli/commands/doctor-fixes.js +119 -20
- package/dist/src/cli/commands/hooks.js +2 -1
- package/dist/src/cli/commands/mcp.js +3 -2
- package/dist/src/cli/commands/memory.js +2 -1
- package/dist/src/cli/commands/performance.js +2 -1
- package/dist/src/cli/commands/retire.js +1 -1
- package/dist/src/cli/commands/spell-schedule.js +2 -1
- package/dist/src/cli/commands/swarm.js +216 -104
- package/dist/src/cli/guidance/headless.js +5 -8
- package/dist/src/cli/guidance/retriever.js +27 -6
- package/dist/src/cli/guidance/ruvbot-integration.js +2 -1
- package/dist/src/cli/guidance/uncertainty.js +2 -1
- package/dist/src/cli/hooks/bridge/official-hooks-bridge.js +2 -1
- package/dist/src/cli/hooks/mcp/index.js +3 -2
- package/dist/src/cli/hooks/reasoningbank/index.js +2 -1
- package/dist/src/cli/hooks/registry/index.js +2 -1
- package/dist/src/cli/hooks/swarm/index.js +6 -5
- package/dist/src/cli/init/claudemd-generator.js +2 -1
- package/dist/src/cli/init/helpers-generator.js +1 -1
- package/dist/src/cli/init/moflo-yaml-template.js +4 -4
- package/dist/src/cli/mcp-client.js +5 -2
- package/dist/src/cli/mcp-tools/agent-tools.js +4 -1
- package/dist/src/cli/mcp-tools/hive-mind-tools.js +4 -3
- package/dist/src/cli/mcp-tools/hooks-tools.js +6 -5
- package/dist/src/cli/mcp-tools/json-store.js +3 -2
- package/dist/src/cli/mcp-tools/neural-tools.js +2 -1
- package/dist/src/cli/mcp-tools/performance-tools.js +2 -1
- package/dist/src/cli/mcp-tools/session-tools.js +4 -2
- package/dist/src/cli/mcp-tools/spell-tools.js +2 -1
- package/dist/src/cli/memory/bridge-core.js +8 -2
- package/dist/src/cli/memory/controllers/_shared.js +8 -2
- package/dist/src/cli/memory/controllers/nightly-learner.js +2 -1
- package/dist/src/cli/memory/domain/services/memory-domain-service.js +2 -1
- package/dist/src/cli/memory/entries-write.js +2 -1
- package/dist/src/cli/memory/intelligence.js +2 -1
- package/dist/src/cli/memory/persistent-sona.js +1 -3
- package/dist/src/cli/memory/types.js +2 -3
- package/dist/src/cli/memory/verify.js +3 -2
- package/dist/src/cli/movector/graph-analyzer.js +14 -3
- package/dist/src/cli/neural/pattern-learner.js +4 -2
- package/dist/src/cli/neural/reasoning-bank.js +2 -1
- package/dist/src/cli/neural/reasoningbank-adapter.js +2 -1
- package/dist/src/cli/neural/sona-manager.js +4 -3
- package/dist/src/cli/production/monitoring.js +2 -1
- package/dist/src/cli/services/daemon-service.js +57 -46
- package/dist/src/cli/services/daemon-spell-executor.js +3 -2
- package/dist/src/cli/services/headless-worker-executor.js +4 -2
- package/dist/src/cli/services/learning-service.js +2 -1
- package/dist/src/cli/services/project-root.js +17 -1
- package/dist/src/cli/services/worker-daemon.js +2 -1
- package/dist/src/cli/shared/hooks/example-usage.js +3 -2
- package/dist/src/cli/shared/hooks/safety/git-commit.js +11 -2
- package/dist/src/cli/shared/hooks/session-hooks.js +3 -2
- package/dist/src/cli/shared/hooks/task-hooks.js +2 -1
- package/dist/src/cli/shared/mcp/session-manager.js +2 -1
- package/dist/src/cli/shared/plugins/official/hive-mind-plugin.js +2 -1
- package/dist/src/cli/shared/plugins/official/maestro-plugin.js +3 -2
- package/dist/src/cli/shared/security/index.js +6 -2
- package/dist/src/cli/shared/utils/atomic-file-write.js +9 -1
- package/dist/src/cli/shared/utils/id.js +54 -0
- package/dist/src/cli/shared/utils/platform.js +36 -5
- package/dist/src/cli/spells/commands/destructive-pattern-checker.js +6 -1
- package/dist/src/cli/spells/core/dry-run-validator.js +2 -1
- package/dist/src/cli/spells/core/interpolation.js +8 -3
- package/dist/src/cli/spells/core/permission-resolver.js +2 -2
- package/dist/src/cli/spells/core/runner.js +2 -1
- package/dist/src/cli/spells/core/shell.js +7 -8
- package/dist/src/cli/spells/factory/runner-bridge.js +3 -2
- package/dist/src/cli/spells/factory/runner-factory.js +3 -2
- package/dist/src/cli/spells/scheduler/scheduler.js +2 -1
- package/dist/src/cli/swarm/consensus/gossip.js +2 -1
- package/dist/src/cli/swarm/federation-hub.js +5 -4
- package/dist/src/cli/swarm/queen-coordinator.js +5 -4
- package/dist/src/cli/swarm/shared/events.js +2 -1
- package/dist/src/cli/swarm/unified-coordinator.js +3 -2
- package/dist/src/cli/version.js +1 -1
- package/package.json +2 -2
- package/retired-files.json +0 -72
- package/dist/src/cli/mcp-tools/coordination-tools.js +0 -86
- package/dist/src/cli/shared/security/secure-random.js +0 -142
|
@@ -24,13 +24,44 @@ export function getShell() {
|
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Escape a shell argument in a platform-appropriate way.
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
*
|
|
28
|
+
* **This is the canonical implementation.** Every other copy in the tree
|
|
29
|
+
* re-exports it (`spells/core/shell.ts`) or, where a plain `.mjs` cannot import
|
|
30
|
+
* TS, mirrors it with a pointer back here (`harness/consumer-smoke/lib/proc.mjs`).
|
|
31
|
+
*
|
|
32
|
+
* On Windows the wrapping is `"…"` and backslashes matter: under MSVCRT argv
|
|
33
|
+
* parsing a backslash is only special immediately before a `"`, where it escapes
|
|
34
|
+
* it. Escaping quotes alone — the previous behaviour — left a trailing backslash
|
|
35
|
+
* escaping the *closing* quote, so `C:\Users\eric\` became `"C:\Users\eric\"`,
|
|
36
|
+
* the quoted region ran on, and it swallowed the next argument. Windows paths
|
|
37
|
+
* produce that shape constantly (#1419). So: double every run of backslashes
|
|
38
|
+
* that precedes a `"` or terminates the string, then escape the quotes.
|
|
39
|
+
*
|
|
40
|
+
* On Unix the `'\''` idiom is already total — single quotes suppress every other
|
|
41
|
+
* metacharacter — and is unchanged.
|
|
42
|
+
*
|
|
43
|
+
* Scope: this makes the argument survive the C runtime's argv split. It does not
|
|
44
|
+
* neutralise `cmd.exe`'s own `%VAR%` expansion, which happens before the runtime
|
|
45
|
+
* ever sees the string; prefer passing an argv array with `shell: false` when the
|
|
46
|
+
* call site allows it.
|
|
29
47
|
*/
|
|
30
48
|
export function escapeShellArg(arg) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
49
|
+
return IS_WINDOWS ? escapeShellArgWindows(arg) : escapeShellArgPosix(arg);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The Windows branch of {@link escapeShellArg}, exported so it can be tested
|
|
53
|
+
* from any host. Rule #1: a Windows-only code path guarded by `IS_WINDOWS` is a
|
|
54
|
+
* path that a Linux CI run never executes, which is how the trailing-backslash
|
|
55
|
+
* defect survived — including in the smoke harness built to catch exactly this.
|
|
56
|
+
*/
|
|
57
|
+
export function escapeShellArgWindows(arg) {
|
|
58
|
+
const escaped = arg
|
|
59
|
+
.replace(/(\\*)"/g, '$1$1\\"') // backslash run before a quote: double it, then escape the quote
|
|
60
|
+
.replace(/(\\+)$/, '$1$1'); // backslash run before the closing quote: double it
|
|
61
|
+
return `"${escaped}"`;
|
|
62
|
+
}
|
|
63
|
+
/** The POSIX branch of {@link escapeShellArg}, exported for the same reason. */
|
|
64
|
+
export function escapeShellArgPosix(arg) {
|
|
34
65
|
return "'" + arg.replace(/'/g, "'\\''") + "'";
|
|
35
66
|
}
|
|
36
67
|
//# sourceMappingURL=platform.js.map
|
|
@@ -19,8 +19,13 @@ const DENYLIST = [
|
|
|
19
19
|
// /lib, /boot, /root, /home (alone — not /home/user/project/dist),
|
|
20
20
|
// C:\ (Windows root).
|
|
21
21
|
// End-of-string OR followed by space/wildcard — NOT followed by more path.
|
|
22
|
+
// The flag group is `[^rfRF\W]*[rfRF]\w*`, not `\w*[rfRF]\w*`: forcing the
|
|
23
|
+
// leading run to exclude r/f pins each match to the FIRST r/f in the token, so
|
|
24
|
+
// a flag can be split exactly one way. The ambiguous form inside the outer `*`
|
|
25
|
+
// backtracked exponentially on `rm ` + repeated `-ff\t`, and a safety gate
|
|
26
|
+
// that hangs is a safety gate that is not enforcing (#1418).
|
|
22
27
|
{
|
|
23
|
-
regex: /\brm\s+(
|
|
28
|
+
regex: /\brm\s+(?:-[^rfRF\W]*[rfRF]\w*\s+)*(?:\/(?:\s|$|\*)|~(?:\/?\s|\/?\*|$)|(?:\/(?:home|etc|usr|var|bin|sbin|lib|boot|root))(?:\s|$|\*|\/\*)|[A-Z]:\\(?:\s|$|\\?\*))/i,
|
|
24
29
|
pattern: 'Recursive delete of root/home/system directories',
|
|
25
30
|
reason: 'Filesystem wipe — would destroy system or user files',
|
|
26
31
|
},
|
|
@@ -10,6 +10,7 @@ import { resolveArguments } from '../schema/validator.js';
|
|
|
10
10
|
import { checkCapabilities, resolveMofloLevel, } from './capability-validator.js';
|
|
11
11
|
import { collectPrerequisites, checkPrerequisites } from './prerequisite-checker.js';
|
|
12
12
|
import { analyzeStepPermissions, analyzeSpellPermissions } from './permission-disclosure.js';
|
|
13
|
+
import { generateId } from '../../shared/utils/id.js';
|
|
13
14
|
/**
|
|
14
15
|
* Validate a single step for dry-run, returning a report of what WOULD happen.
|
|
15
16
|
*
|
|
@@ -98,7 +99,7 @@ export async function dryRunValidate(definition, resolvedArgs, defValidation, op
|
|
|
98
99
|
? await checkPrerequisites(allPrereqs)
|
|
99
100
|
: [];
|
|
100
101
|
const prereqByName = new Map(prereqResults.map(r => [r.name, r]));
|
|
101
|
-
const spellId =
|
|
102
|
+
const spellId = generateId('dryrun');
|
|
102
103
|
const variables = {};
|
|
103
104
|
const stepReports = [];
|
|
104
105
|
const env = { registry, definition, options, prereqByName };
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Resolves `{stepId.outputKey}` placeholders in spell step configs.
|
|
5
5
|
* Nested property access is supported: `{step1.data.nested.value}`.
|
|
6
6
|
*/
|
|
7
|
+
import { escapeShellArgPosix } from '../../shared/utils/platform.js';
|
|
7
8
|
/**
|
|
8
9
|
* Matches `{path}` variable references in spell step configs.
|
|
9
10
|
*
|
|
@@ -89,9 +90,13 @@ export function interpolateString(template, context) {
|
|
|
89
90
|
* This prevents shell metacharacter injection (`;`, `|`, `` ` ``, `$()`, `&&`, `||`).
|
|
90
91
|
*/
|
|
91
92
|
export function shellEscapeValue(value) {
|
|
92
|
-
// Always
|
|
93
|
-
// for shell interpolation in bash commands (bashCommand hardcodes
|
|
94
|
-
|
|
93
|
+
// Always POSIX single-quote escaping, unconditionally — this function is
|
|
94
|
+
// specifically for shell interpolation in bash commands (bashCommand hardcodes
|
|
95
|
+
// shell: 'bash'), so it must NOT switch to Windows quoting on a Windows host.
|
|
96
|
+
// `escapeShellArgPosix` is exactly that branch, reused rather than re-spelled:
|
|
97
|
+
// this was a third copy of the idiom, and #1419 exists because the second copy
|
|
98
|
+
// went unfixed when the first one did.
|
|
99
|
+
return escapeShellArgPosix(value);
|
|
95
100
|
}
|
|
96
101
|
/**
|
|
97
102
|
* Interpolate `{path}` placeholders with shell-escaped values.
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* 1. Explicit `permissionLevel` on the step definition → use directly
|
|
14
14
|
* 2. Derive from step capabilities: shell → elevated, fs:write → standard, else readonly
|
|
15
15
|
*/
|
|
16
|
+
import { escapeShellArg } from '../../shared/utils/platform.js';
|
|
16
17
|
export const VALID_PERMISSION_LEVELS = [
|
|
17
18
|
'readonly', 'standard', 'elevated', 'autonomous',
|
|
18
19
|
];
|
|
@@ -76,8 +77,7 @@ export function resolvePermissions(explicitLevel, capabilities, additionalTools)
|
|
|
76
77
|
*/
|
|
77
78
|
export function buildClaudeCommand(prompt, explicitLevel, capabilities, additionalTools) {
|
|
78
79
|
const resolved = resolvePermissions(explicitLevel, capabilities, additionalTools);
|
|
79
|
-
|
|
80
|
-
return `claude ${resolved.cliArgs.join(' ')} -p "${escapedPrompt}"`;
|
|
80
|
+
return `claude ${resolved.cliArgs.join(' ')} -p ${escapeShellArg(prompt)}`;
|
|
81
81
|
}
|
|
82
82
|
// ============================================================================
|
|
83
83
|
// Capability → Permission Level Derivation
|
|
@@ -19,6 +19,7 @@ import { resolveEffectiveSandbox, formatSandboxLog, DEFAULT_SANDBOX_CONFIG, } fr
|
|
|
19
19
|
import { checkAcceptance, recordAcceptance } from './permission-acceptance.js';
|
|
20
20
|
import { analyzeSpellPermissions, formatSpellPermissionReport } from './permission-disclosure.js';
|
|
21
21
|
import { createRunBudget, mergeSpellBudgets, } from './run-budget.js';
|
|
22
|
+
import { generateId } from '../../shared/utils/id.js';
|
|
22
23
|
/** Spell engine version. Story #285 (epic #287) — workflow-test constant. */
|
|
23
24
|
export const ENGINE_VERSION = '1.0.0';
|
|
24
25
|
export class SpellCaster {
|
|
@@ -41,7 +42,7 @@ export class SpellCaster {
|
|
|
41
42
|
const defValidation = validateSpellDefinition(definition, {
|
|
42
43
|
knownStepTypes: this.registry.types(),
|
|
43
44
|
});
|
|
44
|
-
const spellId = options.spellId ??
|
|
45
|
+
const spellId = options.spellId ?? generateId('sp');
|
|
45
46
|
if (!defValidation.valid) {
|
|
46
47
|
return this.failureResult(spellId, startTime, [{
|
|
47
48
|
code: 'DEFINITION_VALIDATION_FAILED',
|
|
@@ -46,13 +46,12 @@ export function execFileAsync(file, args, timeout = 30000) {
|
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
|
-
* Escape a string for safe use as a
|
|
50
|
-
*
|
|
49
|
+
* Escape a string for safe use as a shell argument.
|
|
50
|
+
*
|
|
51
|
+
* Re-exported from `shared/utils/platform.ts` rather than redefined: this module
|
|
52
|
+
* carried a near-identical copy, and the Windows branch of that copy had the
|
|
53
|
+
* trailing-backslash defect fixed in #1419. Two implementations meant fixing the
|
|
54
|
+
* same bug twice — or, as happened, once.
|
|
51
55
|
*/
|
|
52
|
-
export
|
|
53
|
-
if (process.platform === 'win32') {
|
|
54
|
-
return `"${arg.replace(/"/g, '\\"')}"`;
|
|
55
|
-
}
|
|
56
|
-
return `'${arg.replace(/'/g, "'\\''")}'`;
|
|
57
|
-
}
|
|
56
|
+
export { escapeShellArg } from '../../shared/utils/platform.js';
|
|
58
57
|
//# sourceMappingURL=shell.js.map
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import { loadSandboxConfigFromProject } from '../core/platform-sandbox.js';
|
|
12
12
|
import { createRunner, runSpellFromContent } from './runner-factory.js';
|
|
13
13
|
import { getDefaultCredentialStore } from '../credentials/default-store.js';
|
|
14
|
+
import { generateId } from '../../shared/utils/id.js';
|
|
14
15
|
/**
|
|
15
16
|
* Resolve sandbox config: prefer caller-supplied; fall back to auto-loading
|
|
16
17
|
* from moflo.yaml at projectRoot. Returns undefined when neither is available
|
|
@@ -32,7 +33,7 @@ const activeSpells = new Map();
|
|
|
32
33
|
* Run a spell from raw file content (YAML/JSON).
|
|
33
34
|
*/
|
|
34
35
|
export async function bridgeRunSpell(content, sourceFile, args, options = {}) {
|
|
35
|
-
const spellId =
|
|
36
|
+
const spellId = generateId('sp');
|
|
36
37
|
const controller = new AbortController();
|
|
37
38
|
activeSpells.set(spellId, controller);
|
|
38
39
|
try {
|
|
@@ -60,7 +61,7 @@ export async function bridgeRunSpell(content, sourceFile, args, options = {}) {
|
|
|
60
61
|
* Run a SpellDefinition directly (for spell_execute).
|
|
61
62
|
*/
|
|
62
63
|
export async function bridgeExecuteSpell(definition, args, options = {}) {
|
|
63
|
-
const spellId = options.spellId ??
|
|
64
|
+
const spellId = options.spellId ?? generateId('sp');
|
|
64
65
|
const controller = new AbortController();
|
|
65
66
|
activeSpells.set(spellId, controller);
|
|
66
67
|
try {
|
|
@@ -16,6 +16,7 @@ import { loadSandboxConfigFromProject } from '../core/platform-sandbox.js';
|
|
|
16
16
|
import { loadSpellBudgetFromProject } from '../core/run-budget.js';
|
|
17
17
|
import { errorDetail } from '../../shared/utils/error-detail.js';
|
|
18
18
|
import { getDefaultCredentialStore } from '../credentials/default-store.js';
|
|
19
|
+
import { generateId } from '../../shared/utils/id.js';
|
|
19
20
|
// ============================================================================
|
|
20
21
|
// Factory
|
|
21
22
|
// ============================================================================
|
|
@@ -58,7 +59,7 @@ export async function runSpellFromContent(content, sourceFile, options = {}) {
|
|
|
58
59
|
}
|
|
59
60
|
catch (err) {
|
|
60
61
|
return {
|
|
61
|
-
spellId: options.spellId ??
|
|
62
|
+
spellId: options.spellId ?? generateId('sp'),
|
|
62
63
|
success: false,
|
|
63
64
|
steps: [],
|
|
64
65
|
outputs: {},
|
|
@@ -70,7 +71,7 @@ export async function runSpellFromContent(content, sourceFile, options = {}) {
|
|
|
70
71
|
const validation = validateSpellDefinition(definition);
|
|
71
72
|
if (!validation.valid) {
|
|
72
73
|
return {
|
|
73
|
-
spellId: options.spellId ??
|
|
74
|
+
spellId: options.spellId ?? generateId('sp'),
|
|
74
75
|
success: false,
|
|
75
76
|
steps: [],
|
|
76
77
|
outputs: {},
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { computeNextRun } from './cron-parser.js';
|
|
8
8
|
import { compareMofloLevels } from '../core/capability-validator.js';
|
|
9
9
|
import { errorDetail } from '../../shared/utils/error-detail.js';
|
|
10
|
+
import { generateId } from '../../shared/utils/id.js';
|
|
10
11
|
// ============================================================================
|
|
11
12
|
// Constants
|
|
12
13
|
// ============================================================================
|
|
@@ -135,7 +136,7 @@ export class SpellScheduler {
|
|
|
135
136
|
if (nextRunAt === null) {
|
|
136
137
|
throw new Error('Could not compute next run time from provided schedule');
|
|
137
138
|
}
|
|
138
|
-
const id =
|
|
139
|
+
const id = generateId('sched-adhoc');
|
|
139
140
|
const record = {
|
|
140
141
|
id,
|
|
141
142
|
spellName: params.spellName,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { EventEmitter } from 'events';
|
|
6
6
|
import { SWARM_CONSTANTS, } from '../types.js';
|
|
7
|
+
import { generateId } from '../../shared/utils/id.js';
|
|
7
8
|
export class GossipConsensus extends EventEmitter {
|
|
8
9
|
config;
|
|
9
10
|
node;
|
|
@@ -359,7 +360,7 @@ export class GossipConsensus extends EventEmitter {
|
|
|
359
360
|
const neighbors = Array.from(this.node.neighbors);
|
|
360
361
|
const randomNeighbor = neighbors[Math.floor(Math.random() * neighbors.length)];
|
|
361
362
|
const stateMessage = {
|
|
362
|
-
id: `state_${this.node.id}_
|
|
363
|
+
id: generateId(`state_${this.node.id}`, { separator: '_' }),
|
|
363
364
|
type: 'state',
|
|
364
365
|
senderId: this.node.id,
|
|
365
366
|
version: this.node.version,
|
|
@@ -24,11 +24,12 @@
|
|
|
24
24
|
* @version 3.0.0-alpha.1
|
|
25
25
|
*/
|
|
26
26
|
import { EventEmitter } from 'events';
|
|
27
|
+
import { generateId } from '../shared/utils/id.js';
|
|
27
28
|
// ============================================================================
|
|
28
29
|
// Default Configuration
|
|
29
30
|
// ============================================================================
|
|
30
31
|
const DEFAULT_CONFIG = {
|
|
31
|
-
federationId:
|
|
32
|
+
federationId: generateId('federation', { separator: '_' }),
|
|
32
33
|
maxEphemeralAgents: 100,
|
|
33
34
|
defaultTTL: 300000, // 5 minutes
|
|
34
35
|
syncIntervalMs: 30000, // 30 seconds
|
|
@@ -264,7 +265,7 @@ export class FederationHub extends EventEmitter {
|
|
|
264
265
|
}
|
|
265
266
|
// Create ephemeral agent
|
|
266
267
|
const ttl = options.ttl || this.config.defaultTTL;
|
|
267
|
-
const agentId =
|
|
268
|
+
const agentId = generateId('ephemeral', { separator: '_' });
|
|
268
269
|
const now = new Date();
|
|
269
270
|
const agent = {
|
|
270
271
|
id: agentId,
|
|
@@ -389,7 +390,7 @@ export class FederationHub extends EventEmitter {
|
|
|
389
390
|
return false;
|
|
390
391
|
}
|
|
391
392
|
const message = {
|
|
392
|
-
id:
|
|
393
|
+
id: generateId('msg', { separator: '_' }),
|
|
393
394
|
type: 'direct',
|
|
394
395
|
sourceSwarmId,
|
|
395
396
|
targetSwarmId,
|
|
@@ -435,7 +436,7 @@ export class FederationHub extends EventEmitter {
|
|
|
435
436
|
throw new Error('Consensus is disabled');
|
|
436
437
|
}
|
|
437
438
|
const proposal = {
|
|
438
|
-
id:
|
|
439
|
+
id: generateId('proposal', { separator: '_' }),
|
|
439
440
|
proposerId,
|
|
440
441
|
type,
|
|
441
442
|
value,
|
|
@@ -47,6 +47,7 @@ const DEFAULT_CONFIG = {
|
|
|
47
47
|
enableFailover: true,
|
|
48
48
|
maxDelegationAttempts: 3,
|
|
49
49
|
};
|
|
50
|
+
import { generateId } from '../shared/utils/id.js';
|
|
50
51
|
// =============================================================================
|
|
51
52
|
// Queen Coordinator Class
|
|
52
53
|
// =============================================================================
|
|
@@ -932,7 +933,7 @@ export class QueenCoordinator extends EventEmitter {
|
|
|
932
933
|
for (const bottleneck of bottlenecks) {
|
|
933
934
|
if (bottleneck.severity === 'critical' || bottleneck.severity === 'high') {
|
|
934
935
|
alerts.push({
|
|
935
|
-
alertId:
|
|
936
|
+
alertId: generateId('alert', { separator: '_' }),
|
|
936
937
|
type: bottleneck.severity === 'critical' ? 'critical' : 'error',
|
|
937
938
|
source: bottleneck.location,
|
|
938
939
|
message: bottleneck.description,
|
|
@@ -947,7 +948,7 @@ export class QueenCoordinator extends EventEmitter {
|
|
|
947
948
|
: 1.0;
|
|
948
949
|
if (avgHealth < 0.5) {
|
|
949
950
|
alerts.push({
|
|
950
|
-
alertId:
|
|
951
|
+
alertId: `${generateId('alert', { separator: '_' })}_health`,
|
|
951
952
|
type: avgHealth < 0.3 ? 'critical' : 'warning',
|
|
952
953
|
source: 'swarm',
|
|
953
954
|
message: `Low average agent health: ${(avgHealth * 100).toFixed(1)}%`,
|
|
@@ -961,7 +962,7 @@ export class QueenCoordinator extends EventEmitter {
|
|
|
961
962
|
: 0;
|
|
962
963
|
if (failureRate > this.config.bottleneckThresholds.errorRate) {
|
|
963
964
|
alerts.push({
|
|
964
|
-
alertId:
|
|
965
|
+
alertId: `${generateId('alert', { separator: '_' })}_failures`,
|
|
965
966
|
type: failureRate > 0.2 ? 'critical' : 'warning',
|
|
966
967
|
source: 'tasks',
|
|
967
968
|
message: `High task failure rate: ${(failureRate * 100).toFixed(1)}%`,
|
|
@@ -1275,7 +1276,7 @@ export class QueenCoordinator extends EventEmitter {
|
|
|
1275
1276
|
}
|
|
1276
1277
|
emitEvent(type, data) {
|
|
1277
1278
|
const event = {
|
|
1278
|
-
id:
|
|
1279
|
+
id: generateId('event', { separator: '_' }),
|
|
1279
1280
|
type,
|
|
1280
1281
|
source: 'queen-coordinator',
|
|
1281
1282
|
timestamp: new Date(),
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* This file provides a complete event system for standalone operation
|
|
6
6
|
* without dependency on @moflo/shared
|
|
7
7
|
*/
|
|
8
|
+
import { generateId } from '../../shared/utils/id.js';
|
|
8
9
|
// =============================================================================
|
|
9
10
|
// Event Bus Implementation
|
|
10
11
|
// =============================================================================
|
|
@@ -127,7 +128,7 @@ export function createEvent(type, source, payload) {
|
|
|
127
128
|
}
|
|
128
129
|
// Helper function to generate event IDs
|
|
129
130
|
function generateEventId() {
|
|
130
|
-
return
|
|
131
|
+
return generateId('evt');
|
|
131
132
|
}
|
|
132
133
|
// Helper function to create a base SwarmEvent
|
|
133
134
|
function createSwarmEvent(type, source, payload) {
|
|
@@ -22,6 +22,7 @@ import { MessageBus } from './message-bus.js';
|
|
|
22
22
|
import { createAgentPool } from './agent-pool.js';
|
|
23
23
|
import { createConsensusEngine } from './consensus/index.js';
|
|
24
24
|
import { fromPersistedTask, isTerminalTaskStatus, } from './swarm-persistence.js';
|
|
25
|
+
import { generateId } from '../shared/utils/id.js';
|
|
25
26
|
// =============================================================================
|
|
26
27
|
// 15-Agent Domain Configuration
|
|
27
28
|
// =============================================================================
|
|
@@ -551,7 +552,7 @@ export class UnifiedSwarmCoordinator extends EventEmitter {
|
|
|
551
552
|
}
|
|
552
553
|
createInitialState() {
|
|
553
554
|
const swarmId = {
|
|
554
|
-
id:
|
|
555
|
+
id: generateId('swarm', { separator: '_' }),
|
|
555
556
|
namespace: 'default',
|
|
556
557
|
version: '3.0.0',
|
|
557
558
|
createdAt: new Date(),
|
|
@@ -1116,7 +1117,7 @@ export class UnifiedSwarmCoordinator extends EventEmitter {
|
|
|
1116
1117
|
}
|
|
1117
1118
|
emitEvent(type, data) {
|
|
1118
1119
|
const event = {
|
|
1119
|
-
id:
|
|
1120
|
+
id: generateId('event', { separator: '_' }),
|
|
1120
1121
|
type,
|
|
1121
1122
|
source: this.state.id.id,
|
|
1122
1123
|
timestamp: new Date(),
|
package/dist/src/cli/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moflo",
|
|
3
|
-
"version": "4.12.
|
|
3
|
+
"version": "4.12.6",
|
|
4
4
|
"description": "MoFlo — AI agent orchestration for Claude Code. A standalone, opinionated toolkit with semantic memory, learned routing, gates, spells, and the /flo issue-execution skill.",
|
|
5
5
|
"main": "dist/src/cli/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"@typescript-eslint/parser": "^8.65.0",
|
|
99
99
|
"eslint": "^10.8.0",
|
|
100
100
|
"glob": "^11.1.0",
|
|
101
|
-
"moflo": "^4.12.
|
|
101
|
+
"moflo": "^4.12.5",
|
|
102
102
|
"tsx": "^4.21.0",
|
|
103
103
|
"typescript": "^5.9.3",
|
|
104
104
|
"vitest": "^4.0.0"
|
package/retired-files.json
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
3
|
"retired": [
|
|
4
|
-
{
|
|
5
|
-
"path": ".claude/agents/analysis/code-analyzer.md",
|
|
6
|
-
"knownContentHashes": [
|
|
7
|
-
"sha256:259bd298e1f6cf297ab5354e4701bec9cf0020bc22a66bba96c09cc580af47f0"
|
|
8
|
-
],
|
|
9
|
-
"retiredIn": "2.0.0-alpha.121"
|
|
10
|
-
},
|
|
11
4
|
{
|
|
12
5
|
"path": ".claude/agents/analysis/code-review/analyze-code-quality.md",
|
|
13
6
|
"knownContentHashes": [
|
|
@@ -16,21 +9,6 @@
|
|
|
16
9
|
],
|
|
17
10
|
"retiredIn": "4.8.12"
|
|
18
11
|
},
|
|
19
|
-
{
|
|
20
|
-
"path": ".claude/agents/architecture/system-design/arch-system-design.md",
|
|
21
|
-
"knownContentHashes": [
|
|
22
|
-
"sha256:7330ff870b23d2d6c05a415fdd9cc7ee6ff49a2cc48a33eb1962b830106abf3b"
|
|
23
|
-
],
|
|
24
|
-
"retiredIn": "3.0.0-alpha.1"
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"path": ".claude/agents/base-template-generator.md",
|
|
28
|
-
"knownContentHashes": [
|
|
29
|
-
"sha256:1bea126c6853067e650e432b1e5cedf588f3161c4995eb1e2e97d04733e24d83",
|
|
30
|
-
"sha256:4b957343021823020828d6d213126243bad177f29984fc09545814b88fcfa87a"
|
|
31
|
-
],
|
|
32
|
-
"retiredIn": "2.0.0-alpha.121"
|
|
33
|
-
},
|
|
34
12
|
{
|
|
35
13
|
"path": ".claude/agents/consensus/byzantine-coordinator.md",
|
|
36
14
|
"knownContentHashes": [
|
|
@@ -96,41 +74,6 @@
|
|
|
96
74
|
"retiredIn": "4.9.21",
|
|
97
75
|
"retiredBy": "#932"
|
|
98
76
|
},
|
|
99
|
-
{
|
|
100
|
-
"path": ".claude/agents/core/coder.md",
|
|
101
|
-
"knownContentHashes": [
|
|
102
|
-
"sha256:fd11f4cf99f74e7db021947e0ecc10f8fd3e5afb357433bcf68058905abf0116"
|
|
103
|
-
],
|
|
104
|
-
"retiredIn": "2.0.0-alpha.121"
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
"path": ".claude/agents/core/planner.md",
|
|
108
|
-
"knownContentHashes": [
|
|
109
|
-
"sha256:1ea85a5cf770f62e7e40e612be9fc5d779dd265f77fa942ee6f8d1c3950127c3"
|
|
110
|
-
],
|
|
111
|
-
"retiredIn": "2.0.0-alpha.121"
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
"path": ".claude/agents/core/researcher.md",
|
|
115
|
-
"knownContentHashes": [
|
|
116
|
-
"sha256:e486075522aef212f49ab79659130521fe362779daf0919fac17f2d1f16576a6"
|
|
117
|
-
],
|
|
118
|
-
"retiredIn": "2.0.0-alpha.121"
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
"path": ".claude/agents/core/reviewer.md",
|
|
122
|
-
"knownContentHashes": [
|
|
123
|
-
"sha256:664518900259644124b28d4b0e92be3ca139fa391920fc0e97b309649bc093fd"
|
|
124
|
-
],
|
|
125
|
-
"retiredIn": "2.0.0-alpha.121"
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
"path": ".claude/agents/core/tester.md",
|
|
129
|
-
"knownContentHashes": [
|
|
130
|
-
"sha256:26f05967316ebbda9b96b7262fe80500d158fcd2f75f1adba1d28c99d882f6e7"
|
|
131
|
-
],
|
|
132
|
-
"retiredIn": "2.0.0-alpha.121"
|
|
133
|
-
},
|
|
134
77
|
{
|
|
135
78
|
"path": ".claude/agents/data/ml/data-ml-model.md",
|
|
136
79
|
"knownContentHashes": [
|
|
@@ -150,21 +93,6 @@
|
|
|
150
93
|
],
|
|
151
94
|
"retiredIn": "4.8.12"
|
|
152
95
|
},
|
|
153
|
-
{
|
|
154
|
-
"path": ".claude/agents/devops/ci-cd/ops-cicd-github.md",
|
|
155
|
-
"knownContentHashes": [
|
|
156
|
-
"sha256:daa1ca3b2e116167dd4d057b64d96bd40c00bfd1d6a3ad3c607dd9129db7a032"
|
|
157
|
-
],
|
|
158
|
-
"retiredIn": "3.0.0-alpha.1"
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
"path": ".claude/agents/documentation/api-docs/docs-api-openapi.md",
|
|
162
|
-
"knownContentHashes": [
|
|
163
|
-
"sha256:0a24f98cd97229b746a2f89f2cdfe09fac0ee8dcd757073017fee91e951b7f7f",
|
|
164
|
-
"sha256:0cec8892de681a157cb3d56af8e336020dae58ec4a51c0e1dcaf6cfd90c61cd7"
|
|
165
|
-
],
|
|
166
|
-
"retiredIn": "3.0.0-alpha.1"
|
|
167
|
-
},
|
|
168
96
|
{
|
|
169
97
|
"path": ".claude/agents/dual-mode/codex-coordinator.md",
|
|
170
98
|
"knownContentHashes": [
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Coordination MCP Tools for CLI
|
|
3
|
-
*
|
|
4
|
-
* Local sync-state surface — tracks last sync time, sync count, conflicts,
|
|
5
|
-
* and pending-change count. Useful for spell orchestration on a single
|
|
6
|
-
* machine; not a distributed protocol.
|
|
7
|
-
*/
|
|
8
|
-
import { createJsonStore } from './json-store.js';
|
|
9
|
-
const store = createJsonStore({
|
|
10
|
-
subdir: 'coordination',
|
|
11
|
-
file: 'store.json',
|
|
12
|
-
defaults: () => ({
|
|
13
|
-
sync: {
|
|
14
|
-
lastSync: new Date().toISOString(),
|
|
15
|
-
syncCount: 0,
|
|
16
|
-
conflicts: 0,
|
|
17
|
-
pendingChanges: 0,
|
|
18
|
-
},
|
|
19
|
-
nodes: {},
|
|
20
|
-
version: '3.0.0',
|
|
21
|
-
}),
|
|
22
|
-
});
|
|
23
|
-
export const coordinationTools = [
|
|
24
|
-
{
|
|
25
|
-
name: 'coordination_sync',
|
|
26
|
-
description: 'Synchronize state across nodes',
|
|
27
|
-
category: 'coordination',
|
|
28
|
-
inputSchema: {
|
|
29
|
-
type: 'object',
|
|
30
|
-
properties: {
|
|
31
|
-
action: { type: 'string', enum: ['status', 'trigger', 'resolve'], description: 'Action to perform' },
|
|
32
|
-
force: { type: 'boolean', description: 'Force synchronization' },
|
|
33
|
-
conflictResolution: { type: 'string', enum: ['latest', 'merge', 'manual'], description: 'Conflict resolution strategy' },
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
handler: async (input) => {
|
|
37
|
-
const state = store.load();
|
|
38
|
-
const action = input.action || 'status';
|
|
39
|
-
if (action === 'status') {
|
|
40
|
-
const timeSinceSync = Date.now() - new Date(state.sync.lastSync).getTime();
|
|
41
|
-
return {
|
|
42
|
-
success: true,
|
|
43
|
-
sync: state.sync,
|
|
44
|
-
timeSinceSync: `${Math.floor(timeSinceSync / 1000)}s`,
|
|
45
|
-
status: state.sync.conflicts > 0 ? 'conflicts' : state.sync.pendingChanges > 0 ? 'pending' : 'synced',
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
if (action === 'trigger') {
|
|
49
|
-
state.sync.syncCount++;
|
|
50
|
-
state.sync.lastSync = new Date().toISOString();
|
|
51
|
-
state.sync.pendingChanges = 0;
|
|
52
|
-
// Simulate sync
|
|
53
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
54
|
-
store.save(state);
|
|
55
|
-
return {
|
|
56
|
-
success: true,
|
|
57
|
-
action: 'synchronized',
|
|
58
|
-
syncCount: state.sync.syncCount,
|
|
59
|
-
syncedAt: state.sync.lastSync,
|
|
60
|
-
nodesSync: Object.keys(state.nodes).length,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
if (action === 'resolve') {
|
|
64
|
-
const strategy = input.conflictResolution || 'latest';
|
|
65
|
-
if (state.sync.conflicts > 0) {
|
|
66
|
-
const resolved = state.sync.conflicts;
|
|
67
|
-
state.sync.conflicts = 0;
|
|
68
|
-
store.save(state);
|
|
69
|
-
return {
|
|
70
|
-
success: true,
|
|
71
|
-
action: 'resolved',
|
|
72
|
-
strategy,
|
|
73
|
-
conflictsResolved: resolved,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
return {
|
|
77
|
-
success: true,
|
|
78
|
-
action: 'resolve',
|
|
79
|
-
message: 'No conflicts to resolve',
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
return { success: false, error: 'Unknown action' };
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
];
|
|
86
|
-
//# sourceMappingURL=coordination-tools.js.map
|