@zachjxyz/moxie 0.6.1 → 0.6.3

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/bin/moxie CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
  # moxie — spec-driven multi-agent development with quorum convergence
3
3
  #
4
- # Pipeline: rfc → audit → fix → plan → build
4
+ # Pipeline: 01-rfc → 02-audit → 03-fix → 04-plan → 05-build
5
5
  # Each phase requires UNANIMOUS quorum from all agents.
6
6
  #
7
7
  # Usage:
@@ -17,7 +17,7 @@
17
17
 
18
18
  set -euo pipefail
19
19
 
20
- MOXIE_VERSION="0.6.1"
20
+ MOXIE_VERSION="0.6.3"
21
21
  # Resolve symlinks (npm installs bin as a symlink)
22
22
  _self="$0"
23
23
  while [ -L "$_self" ]; do
@@ -92,7 +92,7 @@ Usage:
92
92
  moxie key Check key status
93
93
  moxie doctor Check agents and dependencies
94
94
 
95
- Pipeline: rfc → audit → fix → plan → build
95
+ Pipeline: 01-rfc → 02-audit → 03-fix → 04-plan → 05-build
96
96
  Each phase uses randomized agent rotation with UNANIMOUS quorum.
97
97
  The pipeline is durable — it resumes from where it left off.
98
98
  EOF
package/lib/core.sh CHANGED
@@ -4,7 +4,7 @@
4
4
  # ---- Constants ----
5
5
  MOXIE_DIR=".moxie"
6
6
  MOXIE_CONFIG="$MOXIE_DIR/config.toml"
7
- PHASES=(rfc audit fix plan build)
7
+ PHASES=(01-rfc 02-audit 03-fix 04-plan 05-build)
8
8
 
9
9
  # ---- macOS timeout compatibility ----
10
10
  if ! command -v timeout &>/dev/null; then
@@ -101,11 +101,29 @@ banner() {
101
101
 
102
102
  phase_label() {
103
103
  case "$1" in
104
- rfc) echo "RFC" ;;
105
- audit) echo "Audit" ;;
106
- fix) echo "Fix" ;;
107
- plan) echo "Plan" ;;
108
- build) echo "Build" ;;
109
- *) echo "$1" ;;
104
+ 01-rfc) echo "RFC" ;;
105
+ 02-audit) echo "Audit" ;;
106
+ 03-fix) echo "Fix" ;;
107
+ 04-plan) echo "Plan" ;;
108
+ 05-build) echo "Build" ;;
109
+ *) echo "$1" ;;
110
110
  esac
111
111
  }
112
+
113
+ # Resolve a short phase name (rfc) or full name (01-rfc) to the canonical form.
114
+ resolve_phase() {
115
+ case "$1" in
116
+ rfc|01-rfc) echo "01-rfc" ;;
117
+ audit|02-audit) echo "02-audit" ;;
118
+ fix|03-fix) echo "03-fix" ;;
119
+ plan|04-plan) echo "04-plan" ;;
120
+ build|05-build) echo "05-build" ;;
121
+ *) echo "$1" ;;
122
+ esac
123
+ }
124
+
125
+ # Extract the short name from a phase (01-rfc → RFC, 05-build → BUILD)
126
+ phase_prefix() {
127
+ local short="${1#*-}"
128
+ echo "$short" | tr '[:lower:]' '[:upper:]'
129
+ }
package/lib/phases.sh CHANGED
@@ -551,7 +551,7 @@ cmd_init() {
551
551
  This spec will be generated by the RFC phase. The agents will analyze the codebase
552
552
  and produce a comprehensive RFC document that becomes the canonical specification.
553
553
 
554
- See `.moxie/phases/rfc/RFC-FINAL-*.md` once the RFC phase completes.
554
+ See `.moxie/phases/01-rfc/RFC-FINAL-*.md` once the RFC phase completes.
555
555
  SEED
556
556
  else
557
557
  cp "$spec_path" "$MOXIE_DIR/spec.md"
@@ -590,9 +590,9 @@ SEED
590
590
  echo ""
591
591
  echo "Initialized .moxie/ with 5 phases:"
592
592
  if [ "$generate_rfc" = "1" ]; then
593
- echo " rfc (generate) -> audit -> fix -> plan -> build"
593
+ echo " 01-rfc (generate) -> 02-audit -> 03-fix -> 04-plan -> 05-build"
594
594
  else
595
- echo " rfc (review) -> audit -> fix -> plan -> build"
595
+ echo " 01-rfc (review) -> 02-audit -> 03-fix -> 04-plan -> 05-build"
596
596
  fi
597
597
 
598
598
  if [ -d "$MOXIE_DIR/context" ] && [ "$(ls -A "$MOXIE_DIR/context" 2>/dev/null)" ]; then
@@ -615,7 +615,7 @@ _init_ledger() {
615
615
  local ledger="$MOXIE_DIR/phases/$phase/ledger.json"
616
616
 
617
617
  case "$phase" in
618
- rfc)
618
+ 01-rfc)
619
619
  cat > "$ledger" <<'JSON'
620
620
  {
621
621
  "status": "pending",
@@ -624,7 +624,7 @@ _init_ledger() {
624
624
  }
625
625
  JSON
626
626
  ;;
627
- audit)
627
+ 02-audit)
628
628
  cat > "$ledger" <<'JSON'
629
629
  {
630
630
  "status": "pending",
@@ -633,7 +633,7 @@ JSON
633
633
  }
634
634
  JSON
635
635
  ;;
636
- fix)
636
+ 03-fix)
637
637
  cat > "$ledger" <<'JSON'
638
638
  {
639
639
  "status": "pending",
@@ -642,7 +642,7 @@ JSON
642
642
  }
643
643
  JSON
644
644
  ;;
645
- plan)
645
+ 04-plan)
646
646
  cat > "$ledger" <<'JSON'
647
647
  {
648
648
  "status": "pending",
@@ -652,7 +652,7 @@ JSON
652
652
  }
653
653
  JSON
654
654
  ;;
655
- build)
655
+ 05-build)
656
656
  cat > "$ledger" <<'JSON'
657
657
  {
658
658
  "status": "pending",
@@ -728,7 +728,7 @@ sys.exit(0)
728
728
  _phase_is_complete() {
729
729
  local phase="$1"
730
730
  local phase_dir="$MOXIE_DIR/phases/$phase"
731
- local final_prefix="$(echo "$phase" | tr '[:lower:]' '[:upper:]')-FINAL"
731
+ local final_prefix="$(phase_prefix "$phase")-FINAL"
732
732
  ls "$phase_dir"/${final_prefix}-*.md &>/dev/null
733
733
  }
734
734
 
@@ -764,7 +764,7 @@ cmd_run() {
764
764
 
765
765
  while [[ $# -gt 0 ]]; do
766
766
  case "$1" in
767
- --phase) target_phase="$2"; shift 2 ;;
767
+ --phase) target_phase=$(resolve_phase "$2"); shift 2 ;;
768
768
  --dry-run) dry_run=1; shift ;;
769
769
  *) echo "Unknown option: $1" >&2; exit 1 ;;
770
770
  esac
@@ -830,7 +830,7 @@ cmd_start() {
830
830
  local target_phase=""
831
831
  while [[ $# -gt 0 ]]; do
832
832
  case "$1" in
833
- --phase) target_phase="$2"; shift 2 ;;
833
+ --phase) target_phase=$(resolve_phase "$2"); shift 2 ;;
834
834
  *) echo "Unknown option: $1" >&2; exit 1 ;;
835
835
  esac
836
836
  done
@@ -983,7 +983,7 @@ _run_pipeline() {
983
983
 
984
984
  # Resume: skip completed phases
985
985
  if _phase_is_complete "$phase"; then
986
- local final_prefix="$(echo "$phase" | tr '[:lower:]' '[:upper:]')-FINAL"
986
+ local final_prefix="$(phase_prefix "$phase")-FINAL"
987
987
  local final
988
988
  final=$(ls -1 "$MOXIE_DIR/phases/$phase"/${final_prefix}-*.md 2>/dev/null | tail -1)
989
989
  echo ""
@@ -1108,8 +1108,51 @@ _force_accept_best_draft() {
1108
1108
  done
1109
1109
 
1110
1110
  if [ -z "$best" ]; then
1111
- echo " No draft files found to accept." >&2
1112
- return 1
1111
+ # No draft .md files create a synthetic FINAL from the ledger
1112
+ # (common for fix/build phases where agents modify code directly)
1113
+ echo " No draft files found — creating FINAL from ledger state."
1114
+ local ts
1115
+ ts=$(date +"%m%d%y-%H%M%S")
1116
+ local final_file="$phase_dir/${final_prefix}-${ts}.md"
1117
+ python3 -c "
1118
+ import json
1119
+ with open('$ledger') as f:
1120
+ d = json.load(f)
1121
+ lines = ['# $(phase_prefix "${final_prefix%-FINAL}") Phase — Complete', '']
1122
+ lines.append('Phase completed via force-accept (all agents verified).')
1123
+ lines.append('')
1124
+ for name, info in d.get('agents', {}).items():
1125
+ status = 'reached' if info.get('reached') else 'pending'
1126
+ note = info.get('notes', '')
1127
+ lines.append(f'- **{name}**: {status}')
1128
+ if note:
1129
+ lines.append(f' {note}')
1130
+ for item in d.get('findings', d.get('issues', [])):
1131
+ if isinstance(item, str):
1132
+ lines.append(f'- {item}')
1133
+ elif isinstance(item, dict):
1134
+ lines.append(f'- {item}')
1135
+ print('\n'.join(lines))
1136
+ " > "$final_file" 2>/dev/null
1137
+
1138
+ # Mark all agents as reached in the ledger
1139
+ python3 -c "
1140
+ import json, os
1141
+ with open('$ledger') as f:
1142
+ d = json.load(f)
1143
+ for name in d.get('agents', {}):
1144
+ d['agents'][name]['reached'] = True
1145
+ d['status'] = '$(echo "$final_prefix" | tr '[:upper:]' '[:lower:]' | tr '-' '_')'
1146
+ tmp = '$ledger' + '.tmp'
1147
+ with open(tmp, 'w') as f:
1148
+ json.dump(d, f, indent=2)
1149
+ os.rename(tmp, '$ledger')
1150
+ " 2>/dev/null
1151
+
1152
+ echo " Accepted: $(basename "$final_file")"
1153
+ echo ""
1154
+ _show_quorum "$ledger"
1155
+ return 0
1113
1156
  fi
1114
1157
 
1115
1158
  local ts
@@ -1152,10 +1195,10 @@ _run_phase() {
1152
1195
  local prompt_template="$phase_dir/prompt.txt"
1153
1196
  local log_dir="$phase_dir/logs"
1154
1197
  local csv="$phase_dir/token-usage.csv"
1155
- local final_prefix="$(echo "$phase" | tr '[:lower:]' '[:upper:]')-FINAL"
1198
+ local final_prefix="$(phase_prefix "$phase")-FINAL"
1156
1199
 
1157
1200
  local max_rounds=$(toml_get "$MOXIE_CONFIG" "settings.max_rounds" "15")
1158
- if [ "$phase" = "build" ]; then
1201
+ if [ "$phase" = "05-build" ]; then
1159
1202
  max_rounds=$(toml_get "$MOXIE_CONFIG" "settings.max_rounds_build" "50")
1160
1203
  fi
1161
1204
  local turn_timeout=$(toml_get "$MOXIE_CONFIG" "settings.turn_timeout" "900")
@@ -1324,8 +1367,18 @@ with open('$prompt_file', 'w') as f:
1324
1367
  show_phase_tokens "$csv"
1325
1368
  return 0
1326
1369
  else
1327
- echo " All healthy agents reached quorum but FINAL file not yet written."
1328
- echo " Next agent will write it."
1370
+ echo " All healthy agents reached quorum writing FINAL."
1371
+ _force_accept_best_draft "$phase_dir" "$final_prefix" "$ledger"
1372
+ local healthy
1373
+ healthy=$(count_healthy_agents)
1374
+ echo ""
1375
+ echo "╔════════════════════════════════════════════════════════════╗"
1376
+ printf "║ %-58s║\n" "$(phase_label "$phase") phase complete — quorum reached"
1377
+ printf "║ %d/%d agents signed off ║\n" "$healthy" "$AGENT_COUNT"
1378
+ echo "╚════════════════════════════════════════════════════════════╝"
1379
+ echo ""
1380
+ show_phase_tokens "$csv"
1381
+ return 0
1329
1382
  fi
1330
1383
  fi
1331
1384
 
@@ -1483,7 +1536,7 @@ print('1' if d.get('$name', False) else '0')
1483
1536
  for phase in "${PHASES[@]}"; do
1484
1537
  local phase_dir="$MOXIE_DIR/phases/$phase"
1485
1538
  local ledger="$phase_dir/ledger.json"
1486
- local final_prefix="$(echo "$phase" | tr '[:lower:]' '[:upper:]')-FINAL"
1539
+ local final_prefix="$(phase_prefix "$phase")-FINAL"
1487
1540
 
1488
1541
  printf " %-8s" "$(phase_label "$phase"):"
1489
1542
 
@@ -1528,7 +1581,8 @@ else:
1528
1581
  cmd_logs() {
1529
1582
  require_moxie_project
1530
1583
 
1531
- local phase="${1:-}"
1584
+ local phase=""
1585
+ [ -n "${1:-}" ] && phase=$(resolve_phase "$1")
1532
1586
 
1533
1587
  if [ -z "$phase" ]; then
1534
1588
  # Show latest log across all phases
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zachjxyz/moxie",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Run multiple AI coding agents through spec-driven phases with quorum convergence. Supports CLI agents (Claude, Codex, Qwen, Aider, Goose, Amp, Cline, Roo) and Vercel AI Gateway models.",
5
5
  "bin": {
6
6
  "moxie": "bin/moxie"
@@ -2,7 +2,7 @@ You are participating in a multi-agent RFC generation loop for a software projec
2
2
 
3
3
  YOUR AGENT NAME: {{AGENT_NAME}}
4
4
  PROJECT DIRECTORY: {{PROJECT_DIR}}
5
- LEDGER: .moxie/phases/rfc/ledger.json
5
+ LEDGER: .moxie/phases/01-rfc/ledger.json
6
6
  CONTEXT DOCS: .moxie/context/ (if present)
7
7
 
8
8
  ## Context
@@ -15,8 +15,8 @@ can use it as the authoritative source of truth for what the project should do.
15
15
 
16
16
  ### Step 1: Read context
17
17
 
18
- Read the ledger at `.moxie/phases/rfc/ledger.json` to check current state.
19
- If a draft RFC exists (check for `.moxie/phases/rfc/{agent}-*.md` files), read the latest one.
18
+ Read the ledger at `.moxie/phases/01-rfc/ledger.json` to check current state.
19
+ If a draft RFC exists (check for `.moxie/phases/01-rfc/{agent}-*.md` files), read the latest one.
20
20
  If `.moxie/spec.md` exists, read it as the seed document to expand upon.
21
21
  If `.moxie/context/` exists and contains files, read ALL files in it. These are supplementary
22
22
  context documents (roadmaps, existing specs, PRDs, design docs) provided by the user. Use them
@@ -62,11 +62,11 @@ For each section, mark:
62
62
 
63
63
  ### Step 4: Write your output
64
64
 
65
- Save to: `.moxie/phases/rfc/{{AGENT_NAME}}-{MMDDyy-HHmmss}.md`
65
+ Save to: `.moxie/phases/01-rfc/{{AGENT_NAME}}-{MMDDyy-HHmmss}.md`
66
66
 
67
67
  ### Step 5: Update the ledger
68
68
 
69
- Update `.moxie/phases/rfc/ledger.json`:
69
+ Update `.moxie/phases/01-rfc/ledger.json`:
70
70
  - Add your agent to the `agents` map with `output_file` pointing to your file
71
71
  - If you are the FIRST agent (no prior drafts): set `reached: false` (others must review)
72
72
  - If you reviewed the draft and found ZERO inaccuracies/incompletes:
@@ -76,7 +76,7 @@ Update `.moxie/phases/rfc/ledger.json`:
76
76
  ### Step 6: Quorum check
77
77
 
78
78
  If ALL agents (every agent in the config) show `reached: true`:
79
- - Write `.moxie/phases/rfc/RFC-FINAL-{MMDDyy-HHmmss}.md` with the complete RFC
79
+ - Write `.moxie/phases/01-rfc/RFC-FINAL-{MMDDyy-HHmmss}.md` with the complete RFC
80
80
  - Copy the final RFC to `.moxie/spec.md` (this becomes the canonical spec for all later phases)
81
81
  - Set ledger `status` to `"rfc_final"`
82
82
 
@@ -2,7 +2,7 @@ You are participating in a multi-agent audit loop for a software project.
2
2
 
3
3
  YOUR AGENT NAME: {{AGENT_NAME}}
4
4
  SPEC: .moxie/spec.md
5
- LEDGER: .moxie/phases/audit/ledger.json
5
+ LEDGER: .moxie/phases/02-audit/ledger.json
6
6
  CONTEXT DOCS: .moxie/context/ (if present)
7
7
 
8
8
  ## Context
@@ -50,7 +50,7 @@ You MUST read the actual source code to verify — do not just trust the other a
50
50
 
51
51
  ### Step 4: Write your audit
52
52
 
53
- Save to: `.moxie/phases/audit/{{AGENT_NAME}}-{MMDDyy-HHmmss}.md`
53
+ Save to: `.moxie/phases/02-audit/{{AGENT_NAME}}-{MMDDyy-HHmmss}.md`
54
54
 
55
55
  Include:
56
56
  - Your complete findings list
@@ -59,7 +59,7 @@ Include:
59
59
 
60
60
  ### Step 5: Update the ledger
61
61
 
62
- Update `.moxie/phases/audit/ledger.json`:
62
+ Update `.moxie/phases/02-audit/ledger.json`:
63
63
  - Add/update your agent in the `agents` map with `output_file` pointing to your file
64
64
  - If you confirmed ALL findings from ALL prior agents with ZERO new findings and ZERO corrections:
65
65
  set your entry to `reached: true`
@@ -69,7 +69,7 @@ Update `.moxie/phases/audit/ledger.json`:
69
69
 
70
70
  Check if ALL agents (every agent in the project config) show `reached: true`.
71
71
  Only when EVERY agent has independently verified and agreed:
72
- - Write `.moxie/phases/audit/AUDIT-FINAL-{MMDDyy-HHmmss}.md` with:
72
+ - Write `.moxie/phases/02-audit/AUDIT-FINAL-{MMDDyy-HHmmss}.md` with:
73
73
  - The canonical, consolidated list of findings
74
74
  - Severity counts
75
75
  - "Audit phase complete — unanimous quorum reached — ready for fix phase"
@@ -1,8 +1,8 @@
1
1
  You are participating in a multi-agent fix loop for a software project.
2
2
 
3
3
  YOUR AGENT NAME: {{AGENT_NAME}}
4
- LEDGER: .moxie/phases/fix/ledger.json
5
- AUDIT RESULTS: .moxie/phases/audit/AUDIT-FINAL-*.md (find the latest)
4
+ LEDGER: .moxie/phases/03-fix/ledger.json
5
+ AUDIT RESULTS: .moxie/phases/02-audit/AUDIT-FINAL-*.md (find the latest)
6
6
 
7
7
  ## Context
8
8
 
@@ -17,7 +17,7 @@ every fix. Do NOT rubber-stamp or skip verification — thoroughness is the goal
17
17
 
18
18
  ### Step 1: Read the audit findings and ledger
19
19
 
20
- Read `.moxie/phases/fix/ledger.json`. Read the AUDIT-FINAL document.
20
+ Read `.moxie/phases/03-fix/ledger.json`. Read the AUDIT-FINAL document.
21
21
  Check each issue's status:
22
22
  1. First verify fixes by other agents (`status: "fixed"` where you're not `fixed_by`)
23
23
  2. Then fix the next `status: "unfixed"` issue (highest severity first)
@@ -46,7 +46,7 @@ If ANY issue is not fully verified, keep `reached: false`.
46
46
  ### Step 5: Quorum check
47
47
 
48
48
  ALL agents `reached: true` + ALL issues `status: "verified"` →
49
- Write `.moxie/phases/fix/FIX-FINAL-{MMDDyy-HHmmss}.md` with:
49
+ Write `.moxie/phases/03-fix/FIX-FINAL-{MMDDyy-HHmmss}.md` with:
50
50
  - Summary of all fixes applied
51
51
  - Test results
52
52
  - "Fix phase complete — unanimous quorum reached — ready for plan phase"
@@ -2,8 +2,8 @@ You are participating in a multi-agent implementation planning loop for a softwa
2
2
 
3
3
  YOUR AGENT NAME: {{AGENT_NAME}}
4
4
  SPEC: .moxie/spec.md
5
- LEDGER: .moxie/phases/plan/ledger.json
6
- FIX RESULTS: .moxie/phases/fix/FIX-FINAL-*.md (find the latest)
5
+ LEDGER: .moxie/phases/04-plan/ledger.json
6
+ FIX RESULTS: .moxie/phases/03-fix/FIX-FINAL-*.md (find the latest)
7
7
  CONTEXT DOCS: .moxie/context/ (if present)
8
8
 
9
9
  ## Context
@@ -42,7 +42,7 @@ For each section, mark:
42
42
 
43
43
  ### Step 3: Write your review
44
44
 
45
- Save to: `.moxie/phases/plan/{{AGENT_NAME}}-{MMDDyy-HHmmss}.md`
45
+ Save to: `.moxie/phases/04-plan/{{AGENT_NAME}}-{MMDDyy-HHmmss}.md`
46
46
 
47
47
  ### Step 4: Update the ledger
48
48
 
@@ -52,7 +52,7 @@ Save to: `.moxie/phases/plan/{{AGENT_NAME}}-{MMDDyy-HHmmss}.md`
52
52
  ### Step 5: Quorum check
53
53
 
54
54
  ALL agents `reached: true` →
55
- Write `.moxie/phases/plan/PLAN-FINAL-{MMDDyy-HHmmss}.md` with the complete,
55
+ Write `.moxie/phases/04-plan/PLAN-FINAL-{MMDDyy-HHmmss}.md` with the complete,
56
56
  self-contained implementation plan. This is the canonical build spec.
57
57
 
58
58
  Do NOT write the FINAL file unless ALL agents show `reached: true` in the ledger.
@@ -1,8 +1,8 @@
1
1
  You are participating in a multi-agent build loop for a software project.
2
2
 
3
3
  YOUR AGENT NAME: {{AGENT_NAME}}
4
- LEDGER: .moxie/phases/build/ledger.json
5
- BUILD SPEC: .moxie/phases/plan/PLAN-FINAL-*.md (find the latest)
4
+ LEDGER: .moxie/phases/05-build/ledger.json
5
+ BUILD SPEC: .moxie/phases/04-plan/PLAN-FINAL-*.md (find the latest)
6
6
 
7
7
  ## Context
8
8
 
@@ -56,7 +56,7 @@ set `status: "complete"`, advance `current_phase` to the next one.
56
56
  When ALL build phases are `"complete"`:
57
57
  - Set your agent entry to `reached: true`
58
58
  - If ALL agents show `reached: true`:
59
- Write `.moxie/phases/build/BUILD-FINAL-{MMDDyy-HHmmss}.md` with:
59
+ Write `.moxie/phases/05-build/BUILD-FINAL-{MMDDyy-HHmmss}.md` with:
60
60
  - Summary of all phases built
61
61
  - Files created/modified
62
62
  - Test results