murmur8 3.5.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.
Files changed (120) hide show
  1. package/.blueprint/agents/AGENT_BA_CASS.md +239 -0
  2. package/.blueprint/agents/AGENT_DEVELOPER_CODEY.md +308 -0
  3. package/.blueprint/agents/AGENT_SPECIFICATION_ALEX.md +183 -0
  4. package/.blueprint/agents/AGENT_TESTER_NIGEL.md +159 -0
  5. package/.blueprint/agents/GUARDRAILS.md +83 -0
  6. package/.blueprint/agents/TEAM_MANIFESTO.md +91 -0
  7. package/.blueprint/features/.gitkeep +0 -0
  8. package/.blueprint/features/feature_adaptive-retry/FEATURE_SPEC.md +239 -0
  9. package/.blueprint/features/feature_adaptive-retry/IMPLEMENTATION_PLAN.md +48 -0
  10. package/.blueprint/features/feature_adaptive-retry/story-prompt-modification.md +85 -0
  11. package/.blueprint/features/feature_adaptive-retry/story-retry-config.md +89 -0
  12. package/.blueprint/features/feature_adaptive-retry/story-should-retry.md +98 -0
  13. package/.blueprint/features/feature_adaptive-retry/story-strategy-recommendation.md +85 -0
  14. package/.blueprint/features/feature_agent-guardrails/FEATURE_SPEC.md +328 -0
  15. package/.blueprint/features/feature_agent-guardrails/IMPLEMENTATION_PLAN.md +90 -0
  16. package/.blueprint/features/feature_agent-guardrails/story-citation-requirements.md +50 -0
  17. package/.blueprint/features/feature_agent-guardrails/story-confidentiality.md +50 -0
  18. package/.blueprint/features/feature_agent-guardrails/story-escalation-protocol.md +55 -0
  19. package/.blueprint/features/feature_agent-guardrails/story-source-restrictions.md +50 -0
  20. package/.blueprint/features/feature_compressed-feedback/FEATURE_SPEC.md +136 -0
  21. package/.blueprint/features/feature_compressed-feedback/IMPLEMENTATION_PLAN.md +40 -0
  22. package/.blueprint/features/feature_feedback-loop/FEATURE_SPEC.md +347 -0
  23. package/.blueprint/features/feature_feedback-loop/IMPLEMENTATION_PLAN.md +71 -0
  24. package/.blueprint/features/feature_feedback-loop/story-feedback-collection.md +63 -0
  25. package/.blueprint/features/feature_feedback-loop/story-feedback-config.md +61 -0
  26. package/.blueprint/features/feature_feedback-loop/story-feedback-insights.md +63 -0
  27. package/.blueprint/features/feature_feedback-loop/story-quality-gates.md +57 -0
  28. package/.blueprint/features/feature_interactive-alex/FEATURE_SPEC.md +263 -0
  29. package/.blueprint/features/feature_interactive-alex/IMPLEMENTATION_PLAN.md +69 -0
  30. package/.blueprint/features/feature_interactive-alex/handoff-alex.md +19 -0
  31. package/.blueprint/features/feature_interactive-alex/handoff-cass.md +21 -0
  32. package/.blueprint/features/feature_interactive-alex/handoff-nigel.md +19 -0
  33. package/.blueprint/features/feature_interactive-alex/story-flag-routing.md +54 -0
  34. package/.blueprint/features/feature_interactive-alex/story-iterative-drafting.md +65 -0
  35. package/.blueprint/features/feature_interactive-alex/story-pipeline-integration.md +66 -0
  36. package/.blueprint/features/feature_interactive-alex/story-session-lifecycle.md +75 -0
  37. package/.blueprint/features/feature_interactive-alex/story-system-spec-creation.md +57 -0
  38. package/.blueprint/features/feature_lazy-business-context/FEATURE_SPEC.md +140 -0
  39. package/.blueprint/features/feature_lazy-business-context/IMPLEMENTATION_PLAN.md +54 -0
  40. package/.blueprint/features/feature_model-native-features/FEATURE_SPEC.md +174 -0
  41. package/.blueprint/features/feature_model-native-features/IMPLEMENTATION_PLAN.md +45 -0
  42. package/.blueprint/features/feature_parallel-abort/FEATURE_SPEC.md +117 -0
  43. package/.blueprint/features/feature_parallel-confirm/FEATURE_SPEC.md +90 -0
  44. package/.blueprint/features/feature_parallel-features/FEATURE_SPEC.md +291 -0
  45. package/.blueprint/features/feature_parallel-features/IMPLEMENTATION_PLAN.md +73 -0
  46. package/.blueprint/features/feature_parallel-lock/FEATURE_SPEC.md +119 -0
  47. package/.blueprint/features/feature_parallel-logging/FEATURE_SPEC.md +105 -0
  48. package/.blueprint/features/feature_parallel-preflight/FEATURE_SPEC.md +141 -0
  49. package/.blueprint/features/feature_pipeline-history/FEATURE_SPEC.md +239 -0
  50. package/.blueprint/features/feature_pipeline-history/IMPLEMENTATION_PLAN.md +71 -0
  51. package/.blueprint/features/feature_pipeline-history/story-clear-history.md +73 -0
  52. package/.blueprint/features/feature_pipeline-history/story-display-history.md +75 -0
  53. package/.blueprint/features/feature_pipeline-history/story-record-execution.md +76 -0
  54. package/.blueprint/features/feature_pipeline-history/story-show-statistics.md +85 -0
  55. package/.blueprint/features/feature_pipeline-insights/FEATURE_SPEC.md +288 -0
  56. package/.blueprint/features/feature_pipeline-insights/IMPLEMENTATION_PLAN.md +65 -0
  57. package/.blueprint/features/feature_pipeline-insights/story-anomaly-detection.md +71 -0
  58. package/.blueprint/features/feature_pipeline-insights/story-bottleneck-analysis.md +75 -0
  59. package/.blueprint/features/feature_pipeline-insights/story-failure-patterns.md +75 -0
  60. package/.blueprint/features/feature_pipeline-insights/story-json-output.md +75 -0
  61. package/.blueprint/features/feature_pipeline-insights/story-trend-analysis.md +78 -0
  62. package/.blueprint/features/feature_shared-guardrails/FEATURE_SPEC.md +119 -0
  63. package/.blueprint/features/feature_shared-guardrails/IMPLEMENTATION_PLAN.md +34 -0
  64. package/.blueprint/features/feature_shared-guardrails/story-extract-guardrails.md +60 -0
  65. package/.blueprint/features/feature_shared-guardrails/story-update-init-commands.md +63 -0
  66. package/.blueprint/features/feature_slim-agent-prompts/FEATURE_SPEC.md +145 -0
  67. package/.blueprint/features/feature_slim-agent-prompts/IMPLEMENTATION_PLAN.md +87 -0
  68. package/.blueprint/features/feature_slim-agent-prompts/story-create-runtime-prompt-template.md +59 -0
  69. package/.blueprint/features/feature_slim-agent-prompts/story-create-slim-agent-prompts.md +65 -0
  70. package/.blueprint/features/feature_slim-agent-prompts/story-skill-integration.md +53 -0
  71. package/.blueprint/features/feature_smart-story-routing/FEATURE_SPEC.md +147 -0
  72. package/.blueprint/features/feature_smart-story-routing/IMPLEMENTATION_PLAN.md +73 -0
  73. package/.blueprint/features/feature_template-extraction/FEATURE_SPEC.md +134 -0
  74. package/.blueprint/features/feature_template-extraction/IMPLEMENTATION_PLAN.md +46 -0
  75. package/.blueprint/features/feature_upstream-summaries/FEATURE_SPEC.md +150 -0
  76. package/.blueprint/features/feature_upstream-summaries/IMPLEMENTATION_PLAN.md +70 -0
  77. package/.blueprint/features/feature_validate-command/FEATURE_SPEC.md +209 -0
  78. package/.blueprint/features/feature_validate-command/IMPLEMENTATION_PLAN.md +59 -0
  79. package/.blueprint/features/feature_validate-command/story-failure-output.md +61 -0
  80. package/.blueprint/features/feature_validate-command/story-node-version-check.md +52 -0
  81. package/.blueprint/features/feature_validate-command/story-run-validation.md +59 -0
  82. package/.blueprint/features/feature_validate-command/story-success-output.md +50 -0
  83. package/.blueprint/prompts/TEMPLATE.md +65 -0
  84. package/.blueprint/prompts/alex-runtime.md +49 -0
  85. package/.blueprint/prompts/cass-runtime.md +46 -0
  86. package/.blueprint/prompts/codey-implement-runtime.md +52 -0
  87. package/.blueprint/prompts/codey-plan-runtime.md +47 -0
  88. package/.blueprint/prompts/nigel-runtime.md +47 -0
  89. package/.blueprint/system_specification/.gitkeep +0 -0
  90. package/.blueprint/system_specification/SYSTEM_SPEC.md +248 -0
  91. package/.blueprint/templates/FEATURE_SPEC.md +125 -0
  92. package/.blueprint/templates/STORY_TEMPLATE.md +96 -0
  93. package/.blueprint/templates/SYSTEM_SPEC.md +128 -0
  94. package/.blueprint/templates/TEST_TEMPLATE.md +76 -0
  95. package/.blueprint/ways_of_working/DEVELOPMENT_RITUAL.md +178 -0
  96. package/.business_context/README.md +27 -0
  97. package/LICENSE +21 -0
  98. package/README.md +564 -0
  99. package/SKILL.md +840 -0
  100. package/bin/cli.js +388 -0
  101. package/package.json +36 -0
  102. package/src/business-context.js +91 -0
  103. package/src/classifier.js +173 -0
  104. package/src/feedback.js +201 -0
  105. package/src/handoff.js +148 -0
  106. package/src/history.js +306 -0
  107. package/src/index.js +170 -0
  108. package/src/init.js +139 -0
  109. package/src/insights.js +504 -0
  110. package/src/interactive.js +338 -0
  111. package/src/orchestrator.js +217 -0
  112. package/src/parallel.js +1544 -0
  113. package/src/retry.js +274 -0
  114. package/src/stack.js +320 -0
  115. package/src/tools/index.js +27 -0
  116. package/src/tools/prompts.js +45 -0
  117. package/src/tools/schemas.js +38 -0
  118. package/src/tools/validation.js +83 -0
  119. package/src/update.js +112 -0
  120. package/src/validate.js +172 -0
package/bin/cli.js ADDED
@@ -0,0 +1,388 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { init } = require('../src/init');
4
+ const { update } = require('../src/update');
5
+ const { displayQueue, resetQueue } = require('../src/orchestrator');
6
+ const { validate, formatOutput } = require('../src/validate');
7
+ const { displayHistory, showStats, clearHistory } = 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
+ runParallel,
26
+ loadQueue,
27
+ cleanupWorktrees,
28
+ readParallelConfig,
29
+ writeParallelConfig,
30
+ getDefaultParallelConfig,
31
+ abortParallel,
32
+ getLockInfo,
33
+ getDetailedStatus,
34
+ formatDetailedStatus,
35
+ rollbackParallel
36
+ } = require('../src/parallel');
37
+
38
+ const args = process.argv.slice(2);
39
+ const command = args[0];
40
+ const subArg = args[1];
41
+
42
+ function parseFlags(args) {
43
+ const flags = {};
44
+ for (const arg of args) {
45
+ if (arg === '--all') flags.all = true;
46
+ if (arg === '--stats') flags.stats = true;
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 (flags.stats) {
91
+ showStats();
92
+ } else {
93
+ displayHistory({ all: flags.all });
94
+ }
95
+ },
96
+ description: 'View pipeline execution history'
97
+ },
98
+ insights: {
99
+ fn: () => {
100
+ const flags = parseFlags(args);
101
+ if (flags.feedback) {
102
+ displayFeedbackInsights({ json: flags.json });
103
+ } else {
104
+ displayInsights({
105
+ bottlenecks: flags.bottlenecks,
106
+ failures: flags.failures,
107
+ json: flags.json
108
+ });
109
+ }
110
+ },
111
+ description: 'Analyze pipeline history for bottlenecks, failures, and trends'
112
+ },
113
+ 'retry-config': {
114
+ fn: () => {
115
+ if (subArg === 'set') {
116
+ const key = args[2];
117
+ const value = args[3];
118
+ if (!key || !value) {
119
+ console.error('Usage: retry-config set <key> <value>');
120
+ console.error('Valid keys: maxRetries, windowSize, highFailureThreshold');
121
+ process.exit(1);
122
+ }
123
+ setConfigValue(key, value);
124
+ } else if (subArg === 'reset') {
125
+ resetConfig();
126
+ console.log('Retry configuration reset to defaults.');
127
+ } else {
128
+ displayConfig();
129
+ }
130
+ },
131
+ description: 'Manage retry configuration for adaptive retry logic'
132
+ },
133
+ 'feedback-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: feedback-config set <key> <value>');
140
+ console.error('Valid keys: minRatingThreshold, enabled');
141
+ process.exit(1);
142
+ }
143
+ setFeedbackConfigValue(key, value);
144
+ } else if (subArg === 'reset') {
145
+ resetFeedbackConfig();
146
+ console.log('Feedback configuration reset to defaults.');
147
+ } else {
148
+ displayFeedbackConfig();
149
+ }
150
+ },
151
+ description: 'Manage feedback loop configuration'
152
+ },
153
+ 'stack-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: stack-config set <key> <value>');
160
+ console.error('Valid keys: language, runtime, packageManager, frameworks, testRunner, testCommand, linter, tools');
161
+ process.exit(1);
162
+ }
163
+ setStackConfigValue(key, value);
164
+ } else if (subArg === 'reset') {
165
+ resetStackConfig();
166
+ console.log('Stack configuration reset to defaults.');
167
+ } else {
168
+ displayStackConfig();
169
+ }
170
+ },
171
+ description: 'View or modify project tech stack configuration'
172
+ },
173
+ 'parallel-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: parallel-config set <key> <value>');
180
+ console.error('Valid keys: cli, skill, skillFlags, worktreeDir, maxConcurrency, queueFile');
181
+ process.exit(1);
182
+ }
183
+ const config = readParallelConfig();
184
+ if (key === 'maxConcurrency') {
185
+ config[key] = parseInt(value, 10);
186
+ } else {
187
+ config[key] = value;
188
+ }
189
+ writeParallelConfig(config);
190
+ console.log(`Set ${key} = ${value}`);
191
+ } else if (subArg === 'reset') {
192
+ writeParallelConfig(getDefaultParallelConfig());
193
+ console.log('Parallel configuration reset to defaults.');
194
+ } else {
195
+ const config = readParallelConfig();
196
+ console.log('Parallel Configuration\n');
197
+ console.log(` cli: ${config.cli}`);
198
+ console.log(` skill: ${config.skill}`);
199
+ console.log(` skillFlags: ${config.skillFlags}`);
200
+ console.log(` worktreeDir: ${config.worktreeDir}`);
201
+ console.log(` maxConcurrency: ${config.maxConcurrency}`);
202
+ console.log(` maxFeatures: ${config.maxFeatures}`);
203
+ console.log(` timeout: ${config.timeout} min`);
204
+ console.log(` minDiskSpaceMB: ${config.minDiskSpaceMB}`);
205
+ console.log(` queueFile: ${config.queueFile}`);
206
+ console.log('\nTo change: murmur8 parallel-config set <key> <value>');
207
+ }
208
+ },
209
+ description: 'View or modify parallel pipeline configuration'
210
+ },
211
+ parallel: {
212
+ fn: async () => {
213
+ if (subArg === 'status') {
214
+ const detailed = args.includes('--detailed') || args.includes('-d');
215
+ const lock = getLockInfo();
216
+
217
+ if (detailed) {
218
+ const details = getDetailedStatus();
219
+ console.log(formatDetailedStatus(details));
220
+ } else {
221
+ const queue = loadQueue();
222
+
223
+ if (!queue.features || queue.features.length === 0) {
224
+ if (lock) {
225
+ console.log(`Parallel execution in progress (PID: ${lock.pid})`);
226
+ console.log(`Started: ${lock.startedAt}`);
227
+ console.log(`Features: ${lock.features.join(', ')}`);
228
+ } else {
229
+ console.log('No parallel pipelines active.');
230
+ }
231
+ return;
232
+ }
233
+
234
+ console.log('Parallel Pipeline Status\n');
235
+ console.log(formatStatus(queue.features));
236
+ const summary = {
237
+ running: queue.features.filter(f => f.status === 'parallel_running').length,
238
+ pending: queue.features.filter(f => f.status === 'parallel_queued').length,
239
+ completed: queue.features.filter(f => f.status === 'parallel_complete').length,
240
+ failed: queue.features.filter(f => f.status === 'parallel_failed').length,
241
+ conflicts: queue.features.filter(f => f.status === 'merge_conflict').length
242
+ };
243
+ console.log(`\nRunning: ${summary.running} | Pending: ${summary.pending} | Completed: ${summary.completed} | Failed: ${summary.failed} | Conflicts: ${summary.conflicts}`);
244
+
245
+ // Show log paths for running/failed
246
+ const withLogs = queue.features.filter(f =>
247
+ f.logPath && (f.status === 'parallel_running' || f.status === 'parallel_failed')
248
+ );
249
+ if (withLogs.length > 0) {
250
+ console.log('\nLog files:');
251
+ withLogs.forEach(f => console.log(` ${f.slug}: ${f.logPath}`));
252
+ }
253
+
254
+ console.log('\nTip: Use --detailed for progress bars');
255
+ }
256
+ } else if (subArg === 'rollback') {
257
+ const dryRunFlag = args.includes('--dry-run');
258
+ const forceFlag = args.includes('--force');
259
+ await rollbackParallel({ dryRun: dryRunFlag, force: forceFlag });
260
+ } else if (subArg === 'cleanup') {
261
+ const cleaned = await cleanupWorktrees();
262
+ console.log(`Cleaned ${cleaned} worktree(s).`);
263
+ } else if (subArg === 'abort') {
264
+ const cleanupFlag = args.includes('--cleanup');
265
+ await abortParallel({ cleanup: cleanupFlag });
266
+ } else {
267
+ const slugs = args.slice(1).filter(a => !a.startsWith('--') && !a.startsWith('-'));
268
+ if (slugs.length === 0) {
269
+ console.error('Usage: murmur8 parallel <slug1> <slug2> ... [options]');
270
+ console.error('\nOptions:');
271
+ console.error(' --dry-run Preview execution plan without running');
272
+ console.error(' --yes, -y Skip confirmation prompt');
273
+ console.error(' --force Override existing lock');
274
+ console.error(' --verbose Stream output to console (not just logs)');
275
+ console.error(' --skip-preflight Skip feature validation checks');
276
+ console.error(' --max-concurrency=N Set max parallel pipelines (default: 3)');
277
+ console.error('\nSubcommands:');
278
+ console.error(' parallel status Show status of all pipelines');
279
+ console.error(' parallel abort Stop all running pipelines');
280
+ console.error(' parallel cleanup Remove completed/aborted worktrees');
281
+ process.exit(1);
282
+ }
283
+
284
+ const maxFlag = args.find(a => a.startsWith('--max-concurrency='));
285
+ const options = {
286
+ dryRun: args.includes('--dry-run'),
287
+ yes: args.includes('--yes') || args.includes('-y'),
288
+ force: args.includes('--force'),
289
+ verbose: args.includes('--verbose'),
290
+ skipPreflight: args.includes('--skip-preflight')
291
+ };
292
+ if (maxFlag) {
293
+ options.maxConcurrency = parseInt(maxFlag.split('=')[1], 10);
294
+ }
295
+ const result = await runParallel(slugs, options);
296
+ process.exit(result.success ? 0 : 1);
297
+ }
298
+ },
299
+ description: 'Run multiple feature pipelines in parallel using git worktrees'
300
+ },
301
+ help: {
302
+ fn: showHelp,
303
+ description: 'Show this help message'
304
+ }
305
+ };
306
+
307
+ function showHelp() {
308
+ console.log(`
309
+ murmur8 - Multi-agent workflow framework
310
+
311
+ Usage: murmur8 <command> [options]
312
+
313
+ Commands:
314
+ init Initialize .blueprint directory in current project
315
+ update Update agents, templates, and rituals (preserves your content)
316
+ validate Run pre-flight checks to validate project configuration
317
+ queue Show current queue state for /implement-feature pipeline
318
+ queue reset Clear the queue and reset all state
319
+ history View recent pipeline runs (last 10 by default)
320
+ history --all View all pipeline runs
321
+ history --stats View aggregate statistics
322
+ history clear Clear all pipeline history (with confirmation)
323
+ history clear --force Clear all pipeline history (no confirmation)
324
+ insights Analyze pipeline for bottlenecks, failures, and trends
325
+ insights --bottlenecks Show only bottleneck analysis
326
+ insights --failures Show only failure patterns
327
+ insights --feedback Show feedback loop insights (calibration, correlations)
328
+ insights --json Output analysis as JSON
329
+ retry-config View current retry configuration
330
+ retry-config set <key> <value> Modify a config value (maxRetries, windowSize, highFailureThreshold)
331
+ retry-config reset Reset retry configuration to defaults
332
+ feedback-config View current feedback loop configuration
333
+ feedback-config set <key> <value> Modify a config value (minRatingThreshold, enabled)
334
+ feedback-config reset Reset feedback configuration to defaults
335
+ stack-config View current tech stack configuration
336
+ stack-config set <key> <value> Modify a config value (language, runtime, frameworks, etc.)
337
+ stack-config reset Reset tech stack configuration to defaults
338
+ parallel <slugs...> Run multiple feature pipelines in parallel
339
+ parallel <slugs...> --dry-run Show execution plan without running
340
+ parallel <slugs...> --yes Skip confirmation prompt
341
+ parallel <slugs...> --verbose Stream output to console
342
+ parallel <slugs...> --skip-preflight Skip feature validation checks
343
+ parallel status Show status of all parallel pipelines
344
+ parallel status --detailed Show progress bars and stage info
345
+ parallel abort Stop all running pipelines
346
+ parallel abort --cleanup Stop all and remove worktrees
347
+ parallel rollback Undo completed merges and cleanup failures
348
+ parallel rollback --dry-run Preview what would be rolled back
349
+ parallel cleanup Remove completed/aborted worktrees
350
+ parallel-config View parallel pipeline configuration
351
+ parallel-config set <key> <value> Modify config (cli, skill, skillFlags, etc.)
352
+ parallel-config reset Reset parallel configuration to defaults
353
+ help Show this help message
354
+
355
+ Examples:
356
+ npx murmur8 init
357
+ npx murmur8 update
358
+ npx murmur8 validate
359
+ npx murmur8 queue
360
+ npx murmur8 history
361
+ npx murmur8 history --stats
362
+ npx murmur8 insights --feedback
363
+ npx murmur8 feedback-config
364
+ `);
365
+ }
366
+
367
+ async function main() {
368
+ if (!command || command === 'help' || command === '--help' || command === '-h') {
369
+ showHelp();
370
+ process.exit(0);
371
+ }
372
+
373
+ const cmd = commands[command];
374
+ if (!cmd) {
375
+ console.error(`Unknown command: ${command}`);
376
+ console.error('Run "agent-workflow help" for usage information.');
377
+ process.exit(1);
378
+ }
379
+
380
+ try {
381
+ await cmd.fn();
382
+ } catch (error) {
383
+ console.error(`Error: ${error.message}`);
384
+ process.exit(1);
385
+ }
386
+ }
387
+
388
+ main();
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "murmur8",
3
+ "version": "3.5.0",
4
+ "description": "Multi-agent workflow framework for automated feature development",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "murmur8": "bin/cli.js"
8
+ },
9
+ "scripts": {
10
+ "test": "node --test"
11
+ },
12
+ "keywords": [
13
+ "agent",
14
+ "workflow",
15
+ "ai",
16
+ "automation",
17
+ "claude",
18
+ "feature-development"
19
+ ],
20
+ "author": "NewmanJustice",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/NewmanJustice/agent-workflow.git"
24
+ },
25
+ "license": "MIT",
26
+ "engines": {
27
+ "node": ">=18.0.0"
28
+ },
29
+ "files": [
30
+ "bin",
31
+ "src",
32
+ ".blueprint",
33
+ ".business_context",
34
+ "SKILL.md"
35
+ ]
36
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Business context detection and conditional inclusion module.
3
+ *
4
+ * Implements lazy loading of business context by detecting references
5
+ * in feature specs and conditionally including the context directive
6
+ * based on agent name and detection results.
7
+ */
8
+
9
+ /**
10
+ * Detects if a feature spec content references business context.
11
+ * Matches '.business_context' or 'business_context/' patterns.
12
+ *
13
+ * @param {string} featureSpecContent - The content of the feature spec
14
+ * @returns {boolean} True if business context references are found
15
+ */
16
+ function needsBusinessContext(featureSpecContent) {
17
+ return featureSpecContent.includes('.business_context')
18
+ || featureSpecContent.includes('business_context/');
19
+ }
20
+
21
+ /**
22
+ * Parses command arguments for the --include-business-context flag.
23
+ *
24
+ * @param {string[]} args - Array of command line arguments
25
+ * @returns {boolean} True if the flag is present
26
+ */
27
+ function parseIncludeBusinessContextFlag(args) {
28
+ return args.includes('--include-business-context');
29
+ }
30
+
31
+ /**
32
+ * Determines if an agent should receive business context.
33
+ * Alex always gets business context (exception).
34
+ * Override flag forces inclusion for all agents.
35
+ * Otherwise, uses detection result.
36
+ *
37
+ * @param {string} agentName - Name of the agent (alex, cass, nigel, codey)
38
+ * @param {boolean} detected - Whether business context was detected in spec
39
+ * @param {boolean} overrideFlag - Whether --include-business-context flag is set
40
+ * @returns {boolean} True if agent should receive business context
41
+ */
42
+ function shouldIncludeBusinessContext(agentName, detected, overrideFlag) {
43
+ // Alex always gets business context
44
+ if (agentName.toLowerCase() === 'alex') {
45
+ return true;
46
+ }
47
+ // Override flag forces inclusion
48
+ if (overrideFlag) {
49
+ return true;
50
+ }
51
+ // Otherwise use detection result
52
+ return detected;
53
+ }
54
+
55
+ /**
56
+ * Builds queue state object with business context detection result.
57
+ *
58
+ * @param {string} featureSlug - The feature slug identifier
59
+ * @param {boolean} needsContext - Whether business context is needed
60
+ * @returns {object} Queue state object
61
+ */
62
+ function buildQueueState(featureSlug, needsContext) {
63
+ return {
64
+ feature: featureSlug,
65
+ current: {
66
+ stage: 'pending',
67
+ needsBusinessContext: needsContext
68
+ }
69
+ };
70
+ }
71
+
72
+ /**
73
+ * Generates the business context directive for agent prompts.
74
+ *
75
+ * @param {boolean} includeContext - Whether to include the directive
76
+ * @returns {string} The directive string or empty string
77
+ */
78
+ function generateBusinessContextDirective(includeContext) {
79
+ if (includeContext) {
80
+ return 'Business Context: .business_context/';
81
+ }
82
+ return '';
83
+ }
84
+
85
+ module.exports = {
86
+ needsBusinessContext,
87
+ parseIncludeBusinessContextFlag,
88
+ shouldIncludeBusinessContext,
89
+ buildQueueState,
90
+ generateBusinessContextDirective
91
+ };
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Smart Story Routing - Feature Classifier Module
3
+ *
4
+ * Classifies features as "technical" or "user-facing" to determine
5
+ * whether the Cass (story writing) stage should be included in the pipeline.
6
+ */
7
+
8
+ // Technical keywords indicate infrastructure/internal work
9
+ const TECHNICAL_KEYWORDS = [
10
+ 'refactor',
11
+ 'token',
12
+ 'performance',
13
+ 'module',
14
+ 'internal',
15
+ 'infrastructure',
16
+ 'optimization',
17
+ 'extract',
18
+ 'compress',
19
+ 'cache',
20
+ 'schema',
21
+ 'validation',
22
+ 'helper',
23
+ 'utility',
24
+ 'config'
25
+ ];
26
+
27
+ // User-facing keywords indicate customer-visible features
28
+ const USER_FACING_KEYWORDS = [
29
+ 'user',
30
+ 'customer',
31
+ 'ui',
32
+ 'screen',
33
+ 'journey',
34
+ 'flow',
35
+ 'experience',
36
+ 'interface',
37
+ 'form',
38
+ 'button',
39
+ 'login',
40
+ 'signup',
41
+ 'dashboard',
42
+ 'notification',
43
+ 'email'
44
+ ];
45
+
46
+ /**
47
+ * Classify a feature specification as technical or user-facing
48
+ * @param {string} content - The feature specification content
49
+ * @returns {Object} Classification result with type, counts, and reason
50
+ */
51
+ function classifyFeature(content) {
52
+ const lowerContent = (content || '').toLowerCase();
53
+
54
+ let technicalCount = 0;
55
+ let userFacingCount = 0;
56
+ const technicalMatches = [];
57
+ const userFacingMatches = [];
58
+
59
+ // Count technical keyword matches
60
+ for (const keyword of TECHNICAL_KEYWORDS) {
61
+ const regex = new RegExp(`\\b${keyword}\\b`, 'gi');
62
+ const matches = lowerContent.match(regex);
63
+ if (matches) {
64
+ technicalCount += matches.length;
65
+ technicalMatches.push(keyword);
66
+ }
67
+ }
68
+
69
+ // Count user-facing keyword matches
70
+ for (const keyword of USER_FACING_KEYWORDS) {
71
+ const regex = new RegExp(`\\b${keyword}\\b`, 'gi');
72
+ const matches = lowerContent.match(regex);
73
+ if (matches) {
74
+ userFacingCount += matches.length;
75
+ userFacingMatches.push(keyword);
76
+ }
77
+ }
78
+
79
+ // Determine type - tie goes to user-facing (conservative default)
80
+ const type = technicalCount > userFacingCount ? 'technical' : 'user-facing';
81
+
82
+ // Build reason string
83
+ let reason;
84
+ if (technicalCount === 0 && userFacingCount === 0) {
85
+ reason = 'No keywords found, defaulting to user-facing';
86
+ } else if (technicalCount > userFacingCount) {
87
+ reason = `Technical keywords (${technicalMatches.join(', ')}) outweigh user-facing`;
88
+ } else if (userFacingCount > technicalCount) {
89
+ reason = `User-facing keywords (${userFacingMatches.join(', ')}) outweigh technical`;
90
+ } else {
91
+ reason = 'Tie between technical and user-facing, defaulting to user-facing';
92
+ }
93
+
94
+ return {
95
+ type,
96
+ technicalCount,
97
+ userFacingCount,
98
+ reason
99
+ };
100
+ }
101
+
102
+ /**
103
+ * Parse story-related flags from command arguments
104
+ * @param {string[]} args - Array of command arguments
105
+ * @returns {Object} Parsed flags with override value
106
+ */
107
+ function parseStoryFlags(args) {
108
+ const argList = args || [];
109
+
110
+ if (argList.includes('--with-stories')) {
111
+ return { override: 'include' };
112
+ }
113
+
114
+ if (argList.includes('--skip-stories')) {
115
+ return { override: 'skip' };
116
+ }
117
+
118
+ return { override: null };
119
+ }
120
+
121
+ /**
122
+ * Determine whether stories should be included in the pipeline
123
+ * @param {string} featureType - 'technical' or 'user-facing'
124
+ * @param {string|null} override - 'include', 'skip', or null
125
+ * @returns {boolean} Whether to include stories in the pipeline
126
+ */
127
+ function shouldIncludeStories(featureType, override) {
128
+ // Override takes precedence
129
+ if (override === 'include') {
130
+ return true;
131
+ }
132
+ if (override === 'skip') {
133
+ return false;
134
+ }
135
+
136
+ // Default behavior based on classification
137
+ return featureType === 'user-facing';
138
+ }
139
+
140
+ /**
141
+ * Build queue state object with classification data
142
+ * @param {string} slug - Feature slug
143
+ * @param {string} featureType - 'technical' or 'user-facing'
144
+ * @param {boolean} includeStories - Whether stories are included
145
+ * @returns {Object} Queue state object with featureType and skippedCass fields
146
+ */
147
+ function buildClassifiedQueueState(slug, featureType, includeStories) {
148
+ return {
149
+ slug,
150
+ featureType,
151
+ skippedCass: !includeStories
152
+ };
153
+ }
154
+
155
+ /**
156
+ * Log classification result to console
157
+ * @param {Object} result - Classification result from classifyFeature
158
+ */
159
+ function logClassification(result) {
160
+ console.log(`Feature classified as ${result.type}: ${result.reason}`);
161
+ console.log(` Technical indicators: ${result.technicalCount}`);
162
+ console.log(` User-facing indicators: ${result.userFacingCount}`);
163
+ }
164
+
165
+ module.exports = {
166
+ TECHNICAL_KEYWORDS,
167
+ USER_FACING_KEYWORDS,
168
+ classifyFeature,
169
+ parseStoryFlags,
170
+ shouldIncludeStories,
171
+ buildClassifiedQueueState,
172
+ logClassification
173
+ };