murmur8 4.2.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.blueprint/agents/AGENT_SPECIFICATION_ALEX.md +33 -3
- package/.blueprint/features/feature_config-factory/FEATURE_SPEC.md +138 -0
- package/.blueprint/features/feature_config-factory/IMPLEMENTATION_PLAN.md +187 -0
- package/.blueprint/features/feature_config-factory/handoff-nigel.md +57 -0
- package/.blueprint/features/feature_extract-prompt-util/FEATURE_SPEC.md +42 -0
- package/.blueprint/features/feature_fix-status-icons/FEATURE_SPEC.md +37 -0
- package/.blueprint/features/feature_murm-subagent/FEATURE_SPEC.md +137 -0
- package/.blueprint/features/feature_murm-subagent/SKILL_CHANGES.md +345 -0
- package/.blueprint/features/feature_split-cli-commands/FEATURE_SPEC.md +125 -0
- package/.blueprint/features/feature_split-cli-commands/IMPLEMENTATION_PLAN.md +119 -0
- package/.blueprint/features/feature_split-cli-commands/handoff-nigel.md +45 -0
- package/.blueprint/features/feature_theme-adoption/FEATURE_SPEC.md +143 -0
- package/.blueprint/features/feature_theme-adoption/IMPLEMENTATION_PLAN.md +68 -0
- package/.blueprint/features/feature_theme-adoption/handoff-nigel.md +35 -0
- package/.blueprint/templates/BACKLOG_TEMPLATE.md +46 -0
- package/README.md +19 -10
- package/SKILL.md +377 -3
- package/bin/cli.js +20 -411
- package/package.json +1 -1
- package/src/commands/feedback-config.js +32 -0
- package/src/commands/help.js +81 -0
- package/src/commands/history.js +42 -0
- package/src/commands/init.js +12 -0
- package/src/commands/insights.js +23 -0
- package/src/commands/murm-config.js +52 -0
- package/src/commands/murm.js +109 -0
- package/src/commands/queue.js +19 -0
- package/src/commands/retry-config.js +28 -0
- package/src/commands/stack-config.js +32 -0
- package/src/commands/update.js +12 -0
- package/src/commands/utils.js +24 -0
- package/src/commands/validate.js +15 -0
- package/src/config-factory.js +190 -0
- package/src/feedback.js +5 -2
- package/src/init.js +1 -15
- package/src/insights.js +19 -16
- package/src/retry.js +5 -2
- package/src/stack.js +4 -1
- package/src/theme.js +4 -4
- package/src/update.js +2 -15
- package/src/utils.js +26 -0
- package/src/validate.js +5 -12
package/bin/cli.js
CHANGED
|
@@ -1,432 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const { displayQueue, resetQueue } = require('../src/orchestrator');
|
|
6
|
-
const { validate, formatOutput } = require('../src/validate');
|
|
7
|
-
const { displayHistory, showStats, clearHistory, exportHistory } = require('../src/history');
|
|
8
|
-
const { displayInsights } = require('../src/insights');
|
|
9
|
-
const { displayConfig, setConfigValue, resetConfig } = require('../src/retry');
|
|
10
|
-
const {
|
|
11
|
-
displayConfig: displayFeedbackConfig,
|
|
12
|
-
setConfigValue: setFeedbackConfigValue,
|
|
13
|
-
resetConfig: resetFeedbackConfig
|
|
14
|
-
} = require('../src/feedback');
|
|
15
|
-
const {
|
|
16
|
-
displayStackConfig,
|
|
17
|
-
setStackConfigValue,
|
|
18
|
-
resetStackConfig
|
|
19
|
-
} = require('../src/stack');
|
|
20
|
-
const { displayFeedbackInsights } = require('../src/insights');
|
|
21
|
-
const {
|
|
22
|
-
formatStatus,
|
|
23
|
-
getDefaultConfig,
|
|
24
|
-
splitByLimit,
|
|
25
|
-
runMurm,
|
|
26
|
-
loadQueue,
|
|
27
|
-
cleanupWorktrees,
|
|
28
|
-
readMurmConfig,
|
|
29
|
-
writeMurmConfig,
|
|
30
|
-
getDefaultMurmConfig,
|
|
31
|
-
abortMurm,
|
|
32
|
-
getLockInfo,
|
|
33
|
-
getDetailedStatus,
|
|
34
|
-
formatDetailedStatus,
|
|
35
|
-
rollbackMurm
|
|
36
|
-
} = require('../src/murm');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
37
5
|
|
|
38
6
|
const args = process.argv.slice(2);
|
|
39
7
|
const command = args[0];
|
|
40
|
-
const subArg = args[1];
|
|
41
8
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (arg === '--force') flags.force = true;
|
|
48
|
-
if (arg === '--bottlenecks') flags.bottlenecks = true;
|
|
49
|
-
if (arg === '--failures') flags.failures = true;
|
|
50
|
-
if (arg === '--json') flags.json = true;
|
|
51
|
-
if (arg === '--feedback') flags.feedback = true;
|
|
52
|
-
}
|
|
53
|
-
return flags;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const commands = {
|
|
57
|
-
init: {
|
|
58
|
-
fn: init,
|
|
59
|
-
description: 'Initialize .blueprint directory in current project'
|
|
60
|
-
},
|
|
61
|
-
update: {
|
|
62
|
-
fn: update,
|
|
63
|
-
description: 'Update agents, templates, and rituals (preserves your content)'
|
|
64
|
-
},
|
|
65
|
-
queue: {
|
|
66
|
-
fn: () => {
|
|
67
|
-
if (subArg === 'reset') {
|
|
68
|
-
resetQueue();
|
|
69
|
-
console.log('Queue has been reset.');
|
|
70
|
-
} else {
|
|
71
|
-
displayQueue();
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
description: 'Show queue status (use "reset" to clear)'
|
|
75
|
-
},
|
|
76
|
-
validate: {
|
|
77
|
-
fn: async () => {
|
|
78
|
-
const result = await validate();
|
|
79
|
-
const useColor = process.stdout.isTTY || false;
|
|
80
|
-
console.log(formatOutput(result, useColor));
|
|
81
|
-
process.exit(result.exitCode);
|
|
82
|
-
},
|
|
83
|
-
description: 'Run pre-flight checks to validate project configuration'
|
|
84
|
-
},
|
|
85
|
-
history: {
|
|
86
|
-
fn: async () => {
|
|
87
|
-
const flags = parseFlags(args);
|
|
88
|
-
if (subArg === 'clear') {
|
|
89
|
-
await clearHistory({ force: flags.force });
|
|
90
|
-
} else if (subArg === 'export') {
|
|
91
|
-
const exportOpts = {};
|
|
92
|
-
for (const arg of args) {
|
|
93
|
-
if (arg.startsWith('--format=')) exportOpts.format = arg.split('=')[1];
|
|
94
|
-
if (arg.startsWith('--since=')) exportOpts.since = arg.split('=')[1];
|
|
95
|
-
if (arg.startsWith('--until=')) exportOpts.until = arg.split('=')[1];
|
|
96
|
-
if (arg.startsWith('--status=')) exportOpts.status = arg.split('=')[1];
|
|
97
|
-
if (arg.startsWith('--feature=')) exportOpts.feature = arg.split('=')[1];
|
|
98
|
-
if (arg.startsWith('--output=')) exportOpts.output = arg.split('=')[1];
|
|
99
|
-
}
|
|
100
|
-
const result = await exportHistory(exportOpts);
|
|
101
|
-
if (result.exitCode) {
|
|
102
|
-
console.error(`Error: ${result.error}`);
|
|
103
|
-
process.exit(result.exitCode);
|
|
104
|
-
}
|
|
105
|
-
if (result.message) {
|
|
106
|
-
console.log(result.message);
|
|
107
|
-
} else if (result.output) {
|
|
108
|
-
console.log(result.output);
|
|
109
|
-
}
|
|
110
|
-
} else if (flags.stats) {
|
|
111
|
-
showStats();
|
|
112
|
-
} else {
|
|
113
|
-
displayHistory({ all: flags.all });
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
description: 'View pipeline execution history'
|
|
117
|
-
},
|
|
118
|
-
insights: {
|
|
119
|
-
fn: () => {
|
|
120
|
-
const flags = parseFlags(args);
|
|
121
|
-
if (flags.feedback) {
|
|
122
|
-
displayFeedbackInsights({ json: flags.json });
|
|
123
|
-
} else {
|
|
124
|
-
displayInsights({
|
|
125
|
-
bottlenecks: flags.bottlenecks,
|
|
126
|
-
failures: flags.failures,
|
|
127
|
-
json: flags.json
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
description: 'Analyze pipeline history for bottlenecks, failures, and trends'
|
|
132
|
-
},
|
|
133
|
-
'retry-config': {
|
|
134
|
-
fn: () => {
|
|
135
|
-
if (subArg === 'set') {
|
|
136
|
-
const key = args[2];
|
|
137
|
-
const value = args[3];
|
|
138
|
-
if (!key || !value) {
|
|
139
|
-
console.error('Usage: retry-config set <key> <value>');
|
|
140
|
-
console.error('Valid keys: maxRetries, windowSize, highFailureThreshold');
|
|
141
|
-
process.exit(1);
|
|
142
|
-
}
|
|
143
|
-
setConfigValue(key, value);
|
|
144
|
-
} else if (subArg === 'reset') {
|
|
145
|
-
resetConfig();
|
|
146
|
-
console.log('Retry configuration reset to defaults.');
|
|
147
|
-
} else {
|
|
148
|
-
displayConfig();
|
|
149
|
-
}
|
|
150
|
-
},
|
|
151
|
-
description: 'Manage retry configuration for adaptive retry logic'
|
|
152
|
-
},
|
|
153
|
-
'feedback-config': {
|
|
154
|
-
fn: () => {
|
|
155
|
-
if (subArg === 'set') {
|
|
156
|
-
const key = args[2];
|
|
157
|
-
const value = args[3];
|
|
158
|
-
if (!key || !value) {
|
|
159
|
-
console.error('Usage: feedback-config set <key> <value>');
|
|
160
|
-
console.error('Valid keys: minRatingThreshold, enabled');
|
|
161
|
-
process.exit(1);
|
|
162
|
-
}
|
|
163
|
-
setFeedbackConfigValue(key, value);
|
|
164
|
-
} else if (subArg === 'reset') {
|
|
165
|
-
resetFeedbackConfig();
|
|
166
|
-
console.log('Feedback configuration reset to defaults.');
|
|
167
|
-
} else {
|
|
168
|
-
displayFeedbackConfig();
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
description: 'Manage feedback loop configuration'
|
|
172
|
-
},
|
|
173
|
-
'stack-config': {
|
|
174
|
-
fn: () => {
|
|
175
|
-
if (subArg === 'set') {
|
|
176
|
-
const key = args[2];
|
|
177
|
-
const value = args[3];
|
|
178
|
-
if (!key || !value) {
|
|
179
|
-
console.error('Usage: stack-config set <key> <value>');
|
|
180
|
-
console.error('Valid keys: language, runtime, packageManager, frameworks, testRunner, testCommand, linter, tools');
|
|
181
|
-
process.exit(1);
|
|
182
|
-
}
|
|
183
|
-
setStackConfigValue(key, value);
|
|
184
|
-
} else if (subArg === 'reset') {
|
|
185
|
-
resetStackConfig();
|
|
186
|
-
console.log('Stack configuration reset to defaults.');
|
|
187
|
-
} else {
|
|
188
|
-
displayStackConfig();
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
description: 'View or modify project tech stack configuration'
|
|
192
|
-
},
|
|
193
|
-
'murm-config': {
|
|
194
|
-
fn: () => {
|
|
195
|
-
if (subArg === 'set') {
|
|
196
|
-
const key = args[2];
|
|
197
|
-
const value = args[3];
|
|
198
|
-
if (!key || !value) {
|
|
199
|
-
console.error('Usage: murm-config set <key> <value>');
|
|
200
|
-
console.error('Valid keys: cli, skill, skillFlags, worktreeDir, maxConcurrency, queueFile');
|
|
201
|
-
process.exit(1);
|
|
202
|
-
}
|
|
203
|
-
const config = readMurmConfig();
|
|
204
|
-
if (key === 'maxConcurrency') {
|
|
205
|
-
config[key] = parseInt(value, 10);
|
|
206
|
-
} else {
|
|
207
|
-
config[key] = value;
|
|
208
|
-
}
|
|
209
|
-
writeMurmConfig(config);
|
|
210
|
-
console.log(`Set ${key} = ${value}`);
|
|
211
|
-
} else if (subArg === 'reset') {
|
|
212
|
-
writeMurmConfig(getDefaultMurmConfig());
|
|
213
|
-
console.log('Murmuration configuration reset to defaults.');
|
|
214
|
-
} else {
|
|
215
|
-
const config = readMurmConfig();
|
|
216
|
-
console.log('Murmuration Configuration\n');
|
|
217
|
-
console.log(` cli: ${config.cli}`);
|
|
218
|
-
console.log(` skill: ${config.skill}`);
|
|
219
|
-
console.log(` skillFlags: ${config.skillFlags}`);
|
|
220
|
-
console.log(` worktreeDir: ${config.worktreeDir}`);
|
|
221
|
-
console.log(` maxConcurrency: ${config.maxConcurrency}`);
|
|
222
|
-
console.log(` maxFeatures: ${config.maxFeatures}`);
|
|
223
|
-
console.log(` timeout: ${config.timeout} min`);
|
|
224
|
-
console.log(` minDiskSpaceMB: ${config.minDiskSpaceMB}`);
|
|
225
|
-
console.log(` queueFile: ${config.queueFile}`);
|
|
226
|
-
console.log('\nTo change: murmur8 murm-config set <key> <value>');
|
|
227
|
-
console.log('Run pipelines: murmur8 murm <slug1> <slug2> ...');
|
|
228
|
-
}
|
|
229
|
-
},
|
|
230
|
-
description: 'View or modify murmuration pipeline configuration'
|
|
231
|
-
},
|
|
232
|
-
'parallel-config': {
|
|
233
|
-
fn: null, // alias — set below
|
|
234
|
-
description: 'View or modify murmuration pipeline configuration (alias for murm-config)'
|
|
235
|
-
},
|
|
236
|
-
parallel: {
|
|
237
|
-
fn: async () => {
|
|
238
|
-
if (subArg === 'status') {
|
|
239
|
-
const detailed = args.includes('--detailed') || args.includes('-d');
|
|
240
|
-
const lock = getLockInfo();
|
|
241
|
-
|
|
242
|
-
if (detailed) {
|
|
243
|
-
const details = getDetailedStatus();
|
|
244
|
-
console.log(formatDetailedStatus(details));
|
|
245
|
-
} else {
|
|
246
|
-
const queue = loadQueue();
|
|
247
|
-
|
|
248
|
-
if (!queue.features || queue.features.length === 0) {
|
|
249
|
-
if (lock) {
|
|
250
|
-
console.log(`Murmuration execution in progress (PID: ${lock.pid})`);
|
|
251
|
-
console.log(`Started: ${lock.startedAt}`);
|
|
252
|
-
console.log(`Features: ${lock.features.join(', ')}`);
|
|
253
|
-
} else {
|
|
254
|
-
console.log('No murmuration pipelines active.');
|
|
255
|
-
}
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
console.log('Murmuration Pipeline Status\n');
|
|
260
|
-
console.log(formatStatus(queue.features));
|
|
261
|
-
const summary = {
|
|
262
|
-
running: queue.features.filter(f => f.status === 'murm_running').length,
|
|
263
|
-
pending: queue.features.filter(f => f.status === 'murm_queued').length,
|
|
264
|
-
completed: queue.features.filter(f => f.status === 'murm_complete').length,
|
|
265
|
-
failed: queue.features.filter(f => f.status === 'murm_failed').length,
|
|
266
|
-
conflicts: queue.features.filter(f => f.status === 'merge_conflict').length
|
|
267
|
-
};
|
|
268
|
-
console.log(`\nRunning: ${summary.running} | Pending: ${summary.pending} | Completed: ${summary.completed} | Failed: ${summary.failed} | Conflicts: ${summary.conflicts}`);
|
|
269
|
-
|
|
270
|
-
// Show log paths for running/failed
|
|
271
|
-
const withLogs = queue.features.filter(f =>
|
|
272
|
-
f.logPath && (f.status === 'murm_running' || f.status === 'murm_failed')
|
|
273
|
-
);
|
|
274
|
-
if (withLogs.length > 0) {
|
|
275
|
-
console.log('\nLog files:');
|
|
276
|
-
withLogs.forEach(f => console.log(` ${f.slug}: ${f.logPath}`));
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
console.log('\nTip: Use --detailed for progress bars');
|
|
280
|
-
}
|
|
281
|
-
} else if (subArg === 'rollback') {
|
|
282
|
-
const dryRunFlag = args.includes('--dry-run');
|
|
283
|
-
const forceFlag = args.includes('--force');
|
|
284
|
-
await rollbackMurm({ dryRun: dryRunFlag, force: forceFlag });
|
|
285
|
-
} else if (subArg === 'cleanup') {
|
|
286
|
-
const cleaned = await cleanupWorktrees();
|
|
287
|
-
console.log(`Cleaned ${cleaned} worktree(s).`);
|
|
288
|
-
} else if (subArg === 'abort') {
|
|
289
|
-
const cleanupFlag = args.includes('--cleanup');
|
|
290
|
-
await abortMurm({ cleanup: cleanupFlag });
|
|
291
|
-
} else {
|
|
292
|
-
const slugs = args.slice(1).filter(a => !a.startsWith('--') && !a.startsWith('-'));
|
|
293
|
-
if (slugs.length === 0) {
|
|
294
|
-
console.error('Usage: murmur8 murm <slug1> <slug2> ... [options]');
|
|
295
|
-
console.error('\nOptions:');
|
|
296
|
-
console.error(' --dry-run Preview execution plan without running');
|
|
297
|
-
console.error(' --yes, -y Skip confirmation prompt');
|
|
298
|
-
console.error(' --force Override existing lock');
|
|
299
|
-
console.error(' --verbose Stream output to console (not just logs)');
|
|
300
|
-
console.error(' --skip-preflight Skip feature validation checks');
|
|
301
|
-
console.error(' --max-concurrency=N Set max parallel pipelines (default: 3)');
|
|
302
|
-
console.error('\nSubcommands:');
|
|
303
|
-
console.error(' murm status Show status of all pipelines');
|
|
304
|
-
console.error(' murm abort Stop all running pipelines');
|
|
305
|
-
console.error(' murm cleanup Remove completed/aborted worktrees');
|
|
306
|
-
process.exit(1);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const maxFlag = args.find(a => a.startsWith('--max-concurrency='));
|
|
310
|
-
const options = {
|
|
311
|
-
dryRun: args.includes('--dry-run'),
|
|
312
|
-
yes: args.includes('--yes') || args.includes('-y'),
|
|
313
|
-
force: args.includes('--force'),
|
|
314
|
-
verbose: args.includes('--verbose'),
|
|
315
|
-
skipPreflight: args.includes('--skip-preflight')
|
|
316
|
-
};
|
|
317
|
-
if (maxFlag) {
|
|
318
|
-
options.maxConcurrency = parseInt(maxFlag.split('=')[1], 10);
|
|
319
|
-
}
|
|
320
|
-
const result = await runMurm(slugs, options);
|
|
321
|
-
process.exit(result.success ? 0 : 1);
|
|
322
|
-
}
|
|
323
|
-
},
|
|
324
|
-
description: 'Run multiple feature pipelines in parallel using git worktrees'
|
|
325
|
-
},
|
|
326
|
-
murm: {
|
|
327
|
-
fn: null, // alias — set below
|
|
328
|
-
description: 'Run multiple feature pipelines in parallel (murmuration)'
|
|
329
|
-
},
|
|
330
|
-
murmuration: {
|
|
331
|
-
fn: null, // alias — set below
|
|
332
|
-
description: 'Run multiple feature pipelines in parallel (murmuration)'
|
|
333
|
-
},
|
|
334
|
-
help: {
|
|
335
|
-
fn: showHelp,
|
|
336
|
-
description: 'Show this help message'
|
|
337
|
-
}
|
|
9
|
+
// Alias resolution
|
|
10
|
+
const aliases = {
|
|
11
|
+
'parallel': 'murm',
|
|
12
|
+
'murmuration': 'murm',
|
|
13
|
+
'parallel-config': 'murm-config'
|
|
338
14
|
};
|
|
339
15
|
|
|
340
|
-
|
|
341
|
-
commands.murm.fn = commands.parallel.fn;
|
|
342
|
-
commands.murmuration.fn = commands.parallel.fn;
|
|
343
|
-
commands['parallel-config'].fn = commands['murm-config'].fn;
|
|
344
|
-
|
|
345
|
-
function showHelp() {
|
|
346
|
-
console.log(`
|
|
347
|
-
murmur8 - Multi-agent workflow framework
|
|
348
|
-
|
|
349
|
-
Usage: murmur8 <command> [options]
|
|
350
|
-
|
|
351
|
-
Commands:
|
|
352
|
-
init Initialize .blueprint directory in current project
|
|
353
|
-
update Update agents, templates, and rituals (preserves your content)
|
|
354
|
-
validate Run pre-flight checks to validate project configuration
|
|
355
|
-
queue Show current queue state for /implement-feature pipeline
|
|
356
|
-
queue reset Clear the queue and reset all state
|
|
357
|
-
history View recent pipeline runs (last 10 by default)
|
|
358
|
-
history --all View all pipeline runs
|
|
359
|
-
history --stats View aggregate statistics
|
|
360
|
-
history clear Clear all pipeline history (with confirmation)
|
|
361
|
-
history clear --force Clear all pipeline history (no confirmation)
|
|
362
|
-
history export Export history as CSV (default) or JSON
|
|
363
|
-
history export --format=json Export as JSON
|
|
364
|
-
history export --since=YYYY-MM-DD Filter entries on or after date
|
|
365
|
-
history export --until=YYYY-MM-DD Filter entries on or before date
|
|
366
|
-
history export --status=<status> Filter by status (success|failed|paused)
|
|
367
|
-
history export --feature=<slug> Filter by feature slug
|
|
368
|
-
history export --output=<path> Write to file instead of stdout
|
|
369
|
-
insights Analyze pipeline for bottlenecks, failures, and trends
|
|
370
|
-
insights --bottlenecks Show only bottleneck analysis
|
|
371
|
-
insights --failures Show only failure patterns
|
|
372
|
-
insights --feedback Show feedback loop insights (calibration, correlations)
|
|
373
|
-
insights --json Output analysis as JSON
|
|
374
|
-
retry-config View current retry configuration
|
|
375
|
-
retry-config set <key> <value> Modify a config value (maxRetries, windowSize, highFailureThreshold)
|
|
376
|
-
retry-config reset Reset retry configuration to defaults
|
|
377
|
-
feedback-config View current feedback loop configuration
|
|
378
|
-
feedback-config set <key> <value> Modify a config value (minRatingThreshold, enabled)
|
|
379
|
-
feedback-config reset Reset feedback configuration to defaults
|
|
380
|
-
stack-config View current tech stack configuration
|
|
381
|
-
stack-config set <key> <value> Modify a config value (language, runtime, frameworks, etc.)
|
|
382
|
-
stack-config reset Reset tech stack configuration to defaults
|
|
383
|
-
murm <slugs...> Run multiple feature pipelines in parallel (murmuration)
|
|
384
|
-
murm <slugs...> --dry-run Show execution plan without running
|
|
385
|
-
murm <slugs...> --yes Skip confirmation prompt
|
|
386
|
-
murm <slugs...> --verbose Stream output to console
|
|
387
|
-
murm <slugs...> --skip-preflight Skip feature validation checks
|
|
388
|
-
murm status Show status of all parallel pipelines
|
|
389
|
-
murm status --detailed Show progress bars and stage info
|
|
390
|
-
murm abort Stop all running pipelines
|
|
391
|
-
murm abort --cleanup Stop all and remove worktrees
|
|
392
|
-
murm rollback Undo completed merges and cleanup failures
|
|
393
|
-
murm rollback --dry-run Preview what would be rolled back
|
|
394
|
-
murm cleanup Remove completed/aborted worktrees
|
|
395
|
-
murm-config View murmuration pipeline configuration
|
|
396
|
-
murm-config set <key> <value> Modify config (cli, skill, skillFlags, etc.)
|
|
397
|
-
murm-config reset Reset murmuration configuration to defaults
|
|
398
|
-
help Show this help message
|
|
399
|
-
|
|
400
|
-
Aliases: parallel, murmuration (same as murm)
|
|
401
|
-
parallel-config (same as murm-config)
|
|
402
|
-
|
|
403
|
-
Examples:
|
|
404
|
-
npx murmur8 init
|
|
405
|
-
npx murmur8 update
|
|
406
|
-
npx murmur8 validate
|
|
407
|
-
npx murmur8 queue
|
|
408
|
-
npx murmur8 history
|
|
409
|
-
npx murmur8 history --stats
|
|
410
|
-
npx murmur8 insights --feedback
|
|
411
|
-
npx murmur8 murm user-auth dashboard --dry-run
|
|
412
|
-
`);
|
|
413
|
-
}
|
|
16
|
+
const resolvedCommand = aliases[command] || command;
|
|
414
17
|
|
|
18
|
+
// Dynamic command loading
|
|
415
19
|
async function main() {
|
|
20
|
+
// Handle help/no command
|
|
416
21
|
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
417
|
-
|
|
418
|
-
|
|
22
|
+
const help = require('../src/commands/help');
|
|
23
|
+
await help.run(args);
|
|
24
|
+
return;
|
|
419
25
|
}
|
|
420
26
|
|
|
421
|
-
|
|
422
|
-
|
|
27
|
+
// Load and run the command
|
|
28
|
+
const cmdPath = path.join(__dirname, '../src/commands', `${resolvedCommand}.js`);
|
|
29
|
+
|
|
30
|
+
if (!fs.existsSync(cmdPath)) {
|
|
423
31
|
console.error(`Unknown command: ${command}`);
|
|
424
|
-
console.error('Run "
|
|
32
|
+
console.error('Run "murmur8 help" for usage information.');
|
|
425
33
|
process.exit(1);
|
|
426
34
|
}
|
|
427
35
|
|
|
428
36
|
try {
|
|
429
|
-
|
|
37
|
+
const cmd = require(cmdPath);
|
|
38
|
+
await cmd.run(args);
|
|
430
39
|
} catch (error) {
|
|
431
40
|
console.error(`Error: ${error.message}`);
|
|
432
41
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* feedback-config command - Manage feedback loop configuration
|
|
3
|
+
*/
|
|
4
|
+
const {
|
|
5
|
+
displayConfig: displayFeedbackConfig,
|
|
6
|
+
setConfigValue: setFeedbackConfigValue,
|
|
7
|
+
resetConfig: resetFeedbackConfig
|
|
8
|
+
} = require('../feedback');
|
|
9
|
+
|
|
10
|
+
const description = 'Manage feedback loop configuration';
|
|
11
|
+
|
|
12
|
+
async function run(args) {
|
|
13
|
+
const subArg = args[1];
|
|
14
|
+
|
|
15
|
+
if (subArg === 'set') {
|
|
16
|
+
const key = args[2];
|
|
17
|
+
const value = args[3];
|
|
18
|
+
if (!key || !value) {
|
|
19
|
+
console.error('Usage: feedback-config set <key> <value>');
|
|
20
|
+
console.error('Valid keys: minRatingThreshold, enabled');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
setFeedbackConfigValue(key, value);
|
|
24
|
+
} else if (subArg === 'reset') {
|
|
25
|
+
resetFeedbackConfig();
|
|
26
|
+
console.log('Feedback configuration reset to defaults.');
|
|
27
|
+
} else {
|
|
28
|
+
displayFeedbackConfig();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = { run, description };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* help command - Show help message
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const description = 'Show this help message';
|
|
6
|
+
|
|
7
|
+
function showHelp() {
|
|
8
|
+
console.log(`
|
|
9
|
+
murmur8 - Multi-agent workflow framework
|
|
10
|
+
|
|
11
|
+
Usage: murmur8 <command> [options]
|
|
12
|
+
|
|
13
|
+
Commands:
|
|
14
|
+
init Initialize .blueprint directory in current project
|
|
15
|
+
update Update agents, templates, and rituals (preserves your content)
|
|
16
|
+
validate Run pre-flight checks to validate project configuration
|
|
17
|
+
queue Show current queue state for /implement-feature pipeline
|
|
18
|
+
queue reset Clear the queue and reset all state
|
|
19
|
+
history View recent pipeline runs (last 10 by default)
|
|
20
|
+
history --all View all pipeline runs
|
|
21
|
+
history --stats View aggregate statistics
|
|
22
|
+
history clear Clear all pipeline history (with confirmation)
|
|
23
|
+
history clear --force Clear all pipeline history (no confirmation)
|
|
24
|
+
history export Export history as CSV (default) or JSON
|
|
25
|
+
history export --format=json Export as JSON
|
|
26
|
+
history export --since=YYYY-MM-DD Filter entries on or after date
|
|
27
|
+
history export --until=YYYY-MM-DD Filter entries on or before date
|
|
28
|
+
history export --status=<status> Filter by status (success|failed|paused)
|
|
29
|
+
history export --feature=<slug> Filter by feature slug
|
|
30
|
+
history export --output=<path> Write to file instead of stdout
|
|
31
|
+
insights Analyze pipeline for bottlenecks, failures, and trends
|
|
32
|
+
insights --bottlenecks Show only bottleneck analysis
|
|
33
|
+
insights --failures Show only failure patterns
|
|
34
|
+
insights --feedback Show feedback loop insights (calibration, correlations)
|
|
35
|
+
insights --json Output analysis as JSON
|
|
36
|
+
retry-config View current retry configuration
|
|
37
|
+
retry-config set <key> <value> Modify a config value (maxRetries, windowSize, highFailureThreshold)
|
|
38
|
+
retry-config reset Reset retry configuration to defaults
|
|
39
|
+
feedback-config View current feedback loop configuration
|
|
40
|
+
feedback-config set <key> <value> Modify a config value (minRatingThreshold, enabled)
|
|
41
|
+
feedback-config reset Reset feedback configuration to defaults
|
|
42
|
+
stack-config View current tech stack configuration
|
|
43
|
+
stack-config set <key> <value> Modify a config value (language, runtime, frameworks, etc.)
|
|
44
|
+
stack-config reset Reset tech stack configuration to defaults
|
|
45
|
+
murm <slugs...> Run multiple feature pipelines in parallel (murmuration)
|
|
46
|
+
murm <slugs...> --dry-run Show execution plan without running
|
|
47
|
+
murm <slugs...> --yes Skip confirmation prompt
|
|
48
|
+
murm <slugs...> --verbose Stream output to console
|
|
49
|
+
murm <slugs...> --skip-preflight Skip feature validation checks
|
|
50
|
+
murm status Show status of all parallel pipelines
|
|
51
|
+
murm status --detailed Show progress bars and stage info
|
|
52
|
+
murm abort Stop all running pipelines
|
|
53
|
+
murm abort --cleanup Stop all and remove worktrees
|
|
54
|
+
murm rollback Undo completed merges and cleanup failures
|
|
55
|
+
murm rollback --dry-run Preview what would be rolled back
|
|
56
|
+
murm cleanup Remove completed/aborted worktrees
|
|
57
|
+
murm-config View murmuration pipeline configuration
|
|
58
|
+
murm-config set <key> <value> Modify config (cli, skill, skillFlags, etc.)
|
|
59
|
+
murm-config reset Reset murmuration configuration to defaults
|
|
60
|
+
help Show this help message
|
|
61
|
+
|
|
62
|
+
Aliases: parallel, murmuration (same as murm)
|
|
63
|
+
parallel-config (same as murm-config)
|
|
64
|
+
|
|
65
|
+
Examples:
|
|
66
|
+
npx murmur8 init
|
|
67
|
+
npx murmur8 update
|
|
68
|
+
npx murmur8 validate
|
|
69
|
+
npx murmur8 queue
|
|
70
|
+
npx murmur8 history
|
|
71
|
+
npx murmur8 history --stats
|
|
72
|
+
npx murmur8 insights --feedback
|
|
73
|
+
npx murmur8 murm user-auth dashboard --dry-run
|
|
74
|
+
`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function run(args) {
|
|
78
|
+
showHelp();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = { run, description };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* history command - View pipeline execution history
|
|
3
|
+
*/
|
|
4
|
+
const { displayHistory, showStats, clearHistory, exportHistory } = require('../history');
|
|
5
|
+
const { parseFlags } = require('./utils');
|
|
6
|
+
|
|
7
|
+
const description = 'View pipeline execution history';
|
|
8
|
+
|
|
9
|
+
async function run(args) {
|
|
10
|
+
const flags = parseFlags(args);
|
|
11
|
+
const subArg = args[1];
|
|
12
|
+
|
|
13
|
+
if (subArg === 'clear') {
|
|
14
|
+
await clearHistory({ force: flags.force });
|
|
15
|
+
} else if (subArg === 'export') {
|
|
16
|
+
const exportOpts = {};
|
|
17
|
+
for (const arg of args) {
|
|
18
|
+
if (arg.startsWith('--format=')) exportOpts.format = arg.split('=')[1];
|
|
19
|
+
if (arg.startsWith('--since=')) exportOpts.since = arg.split('=')[1];
|
|
20
|
+
if (arg.startsWith('--until=')) exportOpts.until = arg.split('=')[1];
|
|
21
|
+
if (arg.startsWith('--status=')) exportOpts.status = arg.split('=')[1];
|
|
22
|
+
if (arg.startsWith('--feature=')) exportOpts.feature = arg.split('=')[1];
|
|
23
|
+
if (arg.startsWith('--output=')) exportOpts.output = arg.split('=')[1];
|
|
24
|
+
}
|
|
25
|
+
const result = await exportHistory(exportOpts);
|
|
26
|
+
if (result.exitCode) {
|
|
27
|
+
console.error(`Error: ${result.error}`);
|
|
28
|
+
process.exit(result.exitCode);
|
|
29
|
+
}
|
|
30
|
+
if (result.message) {
|
|
31
|
+
console.log(result.message);
|
|
32
|
+
} else if (result.output) {
|
|
33
|
+
console.log(result.output);
|
|
34
|
+
}
|
|
35
|
+
} else if (flags.stats) {
|
|
36
|
+
showStats();
|
|
37
|
+
} else {
|
|
38
|
+
displayHistory({ all: flags.all });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = { run, description };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* init command - Initialize .blueprint directory in current project
|
|
3
|
+
*/
|
|
4
|
+
const { init } = require('../init');
|
|
5
|
+
|
|
6
|
+
const description = 'Initialize .blueprint directory in current project';
|
|
7
|
+
|
|
8
|
+
async function run(args) {
|
|
9
|
+
await init();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = { run, description };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* insights command - Analyze pipeline history for bottlenecks, failures, and trends
|
|
3
|
+
*/
|
|
4
|
+
const { displayInsights, displayFeedbackInsights } = require('../insights');
|
|
5
|
+
const { parseFlags } = require('./utils');
|
|
6
|
+
|
|
7
|
+
const description = 'Analyze pipeline history for bottlenecks, failures, and trends';
|
|
8
|
+
|
|
9
|
+
async function run(args) {
|
|
10
|
+
const flags = parseFlags(args);
|
|
11
|
+
|
|
12
|
+
if (flags.feedback) {
|
|
13
|
+
displayFeedbackInsights({ json: flags.json });
|
|
14
|
+
} else {
|
|
15
|
+
displayInsights({
|
|
16
|
+
bottlenecks: flags.bottlenecks,
|
|
17
|
+
failures: flags.failures,
|
|
18
|
+
json: flags.json
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = { run, description };
|