omniconductor 0.6.0 → 1.0.1
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/CHANGELOG.md +63 -0
- package/README.md +16 -12
- package/VISION.md +2 -2
- package/adapters/README.md +8 -8
- package/adapters/claude/README.md +2 -5
- package/adapters/claude/SUPPORTED-FEATURES.md +1 -1
- package/adapters/claude/metadata.json +39 -0
- package/adapters/claude/transform.sh +198 -34
- package/adapters/codex/README.md +23 -27
- package/adapters/codex/metadata.json +35 -0
- package/adapters/codex/transform-spec.md +5 -6
- package/adapters/codex/transform.sh +282 -35
- package/adapters/copilot/README.md +26 -29
- package/adapters/copilot/metadata.json +36 -0
- package/adapters/copilot/transform.sh +124 -33
- package/adapters/cursor/README.md +31 -30
- package/adapters/cursor/metadata.json +35 -0
- package/adapters/cursor/transform.sh +115 -26
- package/adapters/gemini/README.md +14 -15
- package/adapters/gemini/metadata.json +36 -0
- package/adapters/gemini/transform.sh +310 -34
- package/adapters/windsurf/README.md +20 -19
- package/adapters/windsurf/metadata.json +36 -0
- package/adapters/windsurf/transform.sh +137 -53
- package/bin/doctor.js +257 -0
- package/bin/omniconductor.js +15 -2
- package/core/anti-patterns/frequent-rule-file-edit.md +1 -1
- package/core/anti-patterns/single-monolithic-rule-file.md +1 -1
- package/core/recipes/README.md +2 -2
- package/core/universal-rules/README.md +4 -4
- package/core/universal-rules/meta-discipline.md +4 -4
- package/core/universal-rules/spec-as-you-go.md +1 -1
- package/docs/ADAPTER-LIVE-VERIFICATION.md +73 -0
- package/docs/COMPARISON.md +133 -0
- package/docs/COMPATIBILITY-MATRIX.md +126 -0
- package/docs/DESIGN-DECISIONS.md +1268 -0
- package/docs/MANUAL-INSTALL.md +15 -15
- package/docs/PUBLICATION-POLICY.md +46 -0
- package/docs/PUBLISH-GUIDE.md +141 -0
- package/package.json +7 -1
- package/tools/check-adapter-metadata.sh +211 -0
- package/tools/check-stale-tokens.sh +130 -0
- package/tools/generate-adapter-docs.js +123 -0
- package/tools/live-verify.sh +195 -0
- package/tools/manifest-safety.sh +118 -0
- package/tools/stale-tokens.txt +32 -0
- package/tools/test-install-modes.sh +277 -0
- package/tools/validate-adapter-output.sh +1 -1
|
@@ -34,6 +34,7 @@ set -eu
|
|
|
34
34
|
|
|
35
35
|
TARGET=""
|
|
36
36
|
RECIPES=""
|
|
37
|
+
MODE="full"
|
|
37
38
|
DRY_RUN="false"
|
|
38
39
|
MEASURE_BASELINE="false"
|
|
39
40
|
NO_PROMPT="false"
|
|
@@ -48,6 +49,7 @@ WIZARD_SHOW_ANTI_PATTERNS="false"
|
|
|
48
49
|
while [ $# -gt 0 ]; do
|
|
49
50
|
case "$1" in
|
|
50
51
|
--recipes=*) RECIPES="${1#--recipes=}" ;;
|
|
52
|
+
--mode=*) MODE="${1#--mode=}" ;;
|
|
51
53
|
--dry-run) DRY_RUN="true" ;;
|
|
52
54
|
--measure-baseline) MEASURE_BASELINE="true" ;;
|
|
53
55
|
--no-prompt) NO_PROMPT="true" ;;
|
|
@@ -60,6 +62,11 @@ Usage: bash adapters/claude/transform.sh <target-project> [options]
|
|
|
60
62
|
|
|
61
63
|
Options:
|
|
62
64
|
--recipes=A,B,C Comma-separated list of recipes to install
|
|
65
|
+
--mode=<m> Install preset (ADR-044): full (default) | minimal (rules + recipes
|
|
66
|
+
text + docs + CLAUDE.md; no agents/hooks/hookify) | strict (abort if
|
|
67
|
+
CLAUDE.md exists) | recipes-only (ONLY the selected recipe rule files;
|
|
68
|
+
requires --recipes=) | reflector-only (self-improvement loop standalone:
|
|
69
|
+
recipe + reflector agent + trajectory hook + /reflect)
|
|
63
70
|
--dry-run Preview only — no files written
|
|
64
71
|
--measure-baseline After install, measure cache token baseline (opt-in)
|
|
65
72
|
--no-prompt Skip all interactive prompts; apply sensible defaults (CI-safe)
|
|
@@ -92,12 +99,32 @@ if [ -z "$TARGET" ]; then
|
|
|
92
99
|
exit 1
|
|
93
100
|
fi
|
|
94
101
|
|
|
102
|
+
case "$MODE" in
|
|
103
|
+
full|minimal|strict|recipes-only|reflector-only) : ;;
|
|
104
|
+
*) echo "Error: unknown --mode '$MODE' (one of: full, minimal, strict, recipes-only, reflector-only)" >&2; exit 1 ;;
|
|
105
|
+
esac
|
|
106
|
+
if [ "$MODE" = "reflector-only" ]; then
|
|
107
|
+
if [ -n "$RECIPES" ] && [ "$RECIPES" != "self-improvement" ]; then
|
|
108
|
+
echo "NOTE: --mode=reflector-only ignores --recipes (installs self-improvement only)" >&2
|
|
109
|
+
fi
|
|
110
|
+
RECIPES="self-improvement"
|
|
111
|
+
fi
|
|
112
|
+
if [ "$MODE" = "recipes-only" ] && [ -z "$RECIPES" ] && [ "$UNINSTALL" != "true" ]; then
|
|
113
|
+
echo "Error: --mode=recipes-only requires --recipes=A,B,..." >&2
|
|
114
|
+
exit 1
|
|
115
|
+
fi
|
|
116
|
+
|
|
95
117
|
# Resolve CONDUCTOR root (where this script lives: adapters/claude/).
|
|
96
118
|
CONDUCTOR_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
97
119
|
CORE_ROOT="$CONDUCTOR_ROOT/core"
|
|
98
120
|
TOOLS_ROOT="$CONDUCTOR_ROOT/tools"
|
|
99
121
|
[ -d "$CORE_ROOT" ] || { echo "Error: core/ not found at $CORE_ROOT" >&2; exit 1; }
|
|
100
122
|
|
|
123
|
+
# CONDUCTOR package version for the manifest — parsed at runtime from package.json
|
|
124
|
+
# so releases never drift the manifest (falls back to "unknown" on any error).
|
|
125
|
+
CONDUCTOR_VERSION="$(/usr/bin/sed -n -E 's/^[[:space:]]*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/p' "$CONDUCTOR_ROOT/package.json" 2>/dev/null | /usr/bin/head -n 1)"
|
|
126
|
+
[ -n "$CONDUCTOR_VERSION" ] || CONDUCTOR_VERSION="unknown"
|
|
127
|
+
|
|
101
128
|
if [ "$DRY_RUN" = "true" ]; then
|
|
102
129
|
mkdir -p "$TARGET"
|
|
103
130
|
fi
|
|
@@ -243,7 +270,7 @@ backup_if_exists() {
|
|
|
243
270
|
# Manifest is generated using only POSIX shell (no jq dependency). Format:
|
|
244
271
|
#
|
|
245
272
|
# {
|
|
246
|
-
# "version": "
|
|
273
|
+
# "version": "v<CONDUCTOR package.json version>",
|
|
247
274
|
# "install_timestamp": "2026-05-10T12:00:00Z",
|
|
248
275
|
# "conductor_root": "/abs/path/to/conductor",
|
|
249
276
|
# "recipes_enabled": ["monorepo", "i18n"],
|
|
@@ -267,6 +294,9 @@ MANIFEST_STAGE_PATH="" # set by init_manifest()
|
|
|
267
294
|
MANIFEST_TS="" # ISO-8601 install timestamp (set by init_manifest)
|
|
268
295
|
MANIFEST_LAST_BACKUP="" # backup_if_exists writes the backup path here; emit helpers read it
|
|
269
296
|
|
|
297
|
+
# shellcheck source=../../tools/manifest-safety.sh
|
|
298
|
+
. "$CONDUCTOR_ROOT/tools/manifest-safety.sh"
|
|
299
|
+
|
|
270
300
|
init_manifest() {
|
|
271
301
|
# Called once at install start (after wizard, before any emit).
|
|
272
302
|
if [ "$DRY_RUN" = "true" ]; then
|
|
@@ -289,12 +319,13 @@ record_emit() {
|
|
|
289
319
|
local had_backup="false"
|
|
290
320
|
[ -n "$backup" ] && had_backup="true"
|
|
291
321
|
# Escape backslashes and double quotes for JSON.
|
|
292
|
-
local esc_path esc_src esc_backup
|
|
322
|
+
local esc_path esc_src esc_backup emitted_sha
|
|
293
323
|
esc_path="$(printf '%s' "$relpath" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
|
|
294
324
|
esc_src="$(printf '%s' "$src" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
|
|
295
325
|
esc_backup="$(printf '%s' "$backup" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
|
|
296
|
-
|
|
297
|
-
"
|
|
326
|
+
emitted_sha="$(conductor_sha256_file "$TARGET_ABS/$relpath")"
|
|
327
|
+
printf ' {"path": "%s", "source": "%s", "had_backup": %s, "backup_path": "%s", "sha256": "%s"},\n' \
|
|
328
|
+
"$esc_path" "$esc_src" "$had_backup" "$esc_backup" "$emitted_sha" >> "$MANIFEST_STAGE_PATH"
|
|
298
329
|
}
|
|
299
330
|
|
|
300
331
|
finalize_manifest() {
|
|
@@ -343,7 +374,9 @@ finalize_manifest() {
|
|
|
343
374
|
|
|
344
375
|
/bin/cat > "$MANIFEST_PATH" <<EOF
|
|
345
376
|
{
|
|
346
|
-
"version": "
|
|
377
|
+
"version": "v$CONDUCTOR_VERSION",
|
|
378
|
+
"adapter": "claude",
|
|
379
|
+
"mode": "$MODE",
|
|
347
380
|
"install_timestamp": "$MANIFEST_TS",
|
|
348
381
|
"conductor_root": "$CONDUCTOR_ROOT",
|
|
349
382
|
"recipes_enabled": $recipes_json,
|
|
@@ -359,21 +392,19 @@ EOF
|
|
|
359
392
|
# Wrappers around backup_if_exists / cp / write that also remember the backup path so the
|
|
360
393
|
# next record_emit() call can reference it. Keeps emit-step changes minimal.
|
|
361
394
|
backup_and_remember() {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
MANIFEST_LAST_BACKUP="${backup#$TARGET_ABS/}"
|
|
376
|
-
fi
|
|
395
|
+
conductor_manifest_backup_and_remember "$1"
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
# ----- framework detection (ADR-044 — suggest, NEVER auto-switch) ----------
|
|
399
|
+
|
|
400
|
+
detect_coexisting_frameworks() {
|
|
401
|
+
local found=""
|
|
402
|
+
[ -d "$TARGET_ABS/.specify" ] && found="$found Spec-Kit"
|
|
403
|
+
{ [ -d "$TARGET_ABS/_bmad" ] || [ -d "$TARGET_ABS/.bmad-core" ]; } && found="$found BMAD"
|
|
404
|
+
if [ -n "$found" ] && [ "$MODE" = "full" ]; then
|
|
405
|
+
log "NOTE: detected coexisting framework(s):$found"
|
|
406
|
+
log " Consider --mode=recipes-only or --mode=reflector-only to coexist without"
|
|
407
|
+
log " overlapping workflow rules (suggestion only — nothing was changed)."
|
|
377
408
|
fi
|
|
378
409
|
}
|
|
379
410
|
|
|
@@ -424,6 +455,7 @@ do_uninstall() {
|
|
|
424
455
|
local restored=0
|
|
425
456
|
local deleted=0
|
|
426
457
|
local missing=0
|
|
458
|
+
local preserved=0
|
|
427
459
|
|
|
428
460
|
# Iterate manifest entries by line. Tolerate trailing comma absence on last entry.
|
|
429
461
|
while IFS= read -r line; do
|
|
@@ -433,16 +465,27 @@ do_uninstall() {
|
|
|
433
465
|
*) continue ;;
|
|
434
466
|
esac
|
|
435
467
|
entries_count=$((entries_count + 1))
|
|
436
|
-
local rel_path src had_backup backup_path
|
|
468
|
+
local rel_path src had_backup backup_path expected_sha
|
|
437
469
|
rel_path="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"path": *"([^"]*)".*/\1/')"
|
|
438
470
|
src="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"source": *"([^"]*)".*/\1/')"
|
|
439
471
|
had_backup="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"had_backup": *(true|false).*/\1/')"
|
|
440
472
|
backup_path="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"backup_path": *"([^"]*)".*/\1/')"
|
|
473
|
+
expected_sha="$(conductor_manifest_field "$line" sha256 2>/dev/null || true)"
|
|
441
474
|
|
|
442
475
|
local abs_dest="$TARGET_ABS/$rel_path"
|
|
443
476
|
local abs_backup=""
|
|
444
477
|
[ -n "$backup_path" ] && abs_backup="$TARGET_ABS/$backup_path"
|
|
445
478
|
|
|
479
|
+
if [ -f "$abs_dest" ] && ! conductor_manifest_file_matches "$abs_dest" "$expected_sha"; then
|
|
480
|
+
if [ -z "$expected_sha" ]; then
|
|
481
|
+
log " WARNING: preserving $rel_path (legacy manifest has no checksum)"
|
|
482
|
+
else
|
|
483
|
+
log " WARNING: preserving user-modified $rel_path"
|
|
484
|
+
fi
|
|
485
|
+
preserved=$((preserved + 1))
|
|
486
|
+
continue
|
|
487
|
+
fi
|
|
488
|
+
|
|
446
489
|
if [ "$had_backup" = "true" ] && [ -n "$abs_backup" ]; then
|
|
447
490
|
if [ -f "$abs_backup" ]; then
|
|
448
491
|
if [ "$DRY_RUN" = "true" ]; then
|
|
@@ -518,6 +561,7 @@ do_uninstall() {
|
|
|
518
561
|
echo " Backups restored: $restored"
|
|
519
562
|
echo " Files deleted: $deleted"
|
|
520
563
|
echo " Backup-missing deletes: $missing"
|
|
564
|
+
[ "$preserved" -gt 0 ] && echo " User-modified files preserved: $preserved"
|
|
521
565
|
echo "========================================================"
|
|
522
566
|
}
|
|
523
567
|
|
|
@@ -565,6 +609,26 @@ if [ -d "$TARGET_ABS/.claude" ] || [ -f "$TARGET_ABS/CLAUDE.md" ]; then
|
|
|
565
609
|
IS_ADOPTER_CASE="true"
|
|
566
610
|
fi
|
|
567
611
|
|
|
612
|
+
detect_coexisting_frameworks
|
|
613
|
+
|
|
614
|
+
# --mode=strict: never overwrite an existing baseline, even with a backup (ADR-044).
|
|
615
|
+
if [ "$MODE" = "strict" ]; then
|
|
616
|
+
if [ -f "$TARGET_ABS/CLAUDE.md" ]; then
|
|
617
|
+
echo "Error (--mode=strict): $TARGET_ABS/CLAUDE.md already exists — strict mode aborts instead of overwriting a baseline." >&2
|
|
618
|
+
echo " Use --mode=full (timestamped backup + manifest-based restore), or move the file first." >&2
|
|
619
|
+
exit 3
|
|
620
|
+
fi
|
|
621
|
+
if [ -d "$TARGET_ABS/.claude/rules" ] && [ -n "$(/bin/ls -A "$TARGET_ABS/.claude/rules" 2>/dev/null)" ]; then
|
|
622
|
+
echo "Error (--mode=strict): $TARGET_ABS/.claude/rules/ already has files — strict mode never writes next to an existing rules surface." >&2
|
|
623
|
+
exit 3
|
|
624
|
+
fi
|
|
625
|
+
fi
|
|
626
|
+
|
|
627
|
+
# À-la-carte modes are non-interactive by design.
|
|
628
|
+
if [ "$MODE" != "full" ] && [ "$MODE" != "strict" ]; then
|
|
629
|
+
NO_PROMPT="true"
|
|
630
|
+
fi
|
|
631
|
+
|
|
568
632
|
if [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "false" ] && [ "$DRY_RUN" = "false" ]; then
|
|
569
633
|
echo ""
|
|
570
634
|
echo "========================================================"
|
|
@@ -633,7 +697,9 @@ fi
|
|
|
633
697
|
# Initialize manifest before any emit happens.
|
|
634
698
|
init_manifest
|
|
635
699
|
|
|
636
|
-
if [ "$
|
|
700
|
+
if [ "$MODE" = "recipes-only" ] || [ "$MODE" = "reflector-only" ]; then
|
|
701
|
+
log "Step 1/6: universal-rules — skipped (--mode=$MODE is à la carte)"
|
|
702
|
+
elif [ "$WIZARD_APPLY_RULES" = "true" ]; then
|
|
637
703
|
log "Step 1/6: universal-rules → .claude/rules/"
|
|
638
704
|
mkdir_if_real "$TARGET_ABS/.claude/rules"
|
|
639
705
|
|
|
@@ -654,9 +720,16 @@ fi
|
|
|
654
720
|
|
|
655
721
|
# ----- step 2: roles -----------------------------------------------------
|
|
656
722
|
|
|
657
|
-
if [ "$
|
|
723
|
+
if [ "$MODE" = "minimal" ]; then
|
|
724
|
+
log "Step 2/6: roles — skipped (--mode=minimal ships text only)"
|
|
725
|
+
elif [ "$WIZARD_APPLY_RULES" = "true" ]; then
|
|
658
726
|
log "Step 2/6: roles → .claude/agents/"
|
|
659
|
-
|
|
727
|
+
# À la carte without self-improvement must not leave an empty .claude/agents/.
|
|
728
|
+
if [ "$MODE" != "recipes-only" ] && [ "$MODE" != "reflector-only" ]; then
|
|
729
|
+
mkdir_if_real "$TARGET_ABS/.claude/agents"
|
|
730
|
+
else
|
|
731
|
+
case ",$RECIPES," in *",self-improvement,"*) mkdir_if_real "$TARGET_ABS/.claude/agents" ;; esac
|
|
732
|
+
fi
|
|
660
733
|
|
|
661
734
|
# Map each universal role to Claude-native agent frontmatter.
|
|
662
735
|
declare_agent() {
|
|
@@ -683,12 +756,16 @@ EOF
|
|
|
683
756
|
record_emit ".claude/agents/$role.md" "core/roles/$role.md" "$MANIFEST_LAST_BACKUP"
|
|
684
757
|
}
|
|
685
758
|
|
|
759
|
+
if [ "$MODE" != "recipes-only" ] && [ "$MODE" != "reflector-only" ]; then
|
|
686
760
|
declare_agent planner "Architecture, gap analysis, ADRs, trade-off decisions. No implementation code." opus
|
|
687
761
|
declare_agent builder "Multi-file or cross-cutting code implementation (3+ files)." opus
|
|
688
762
|
declare_agent reviewer "Plan validation before implementation. Read-only gatekeeper." opus
|
|
689
763
|
declare_agent helper "Single-file or 1-2-file work where the pattern is established." sonnet
|
|
690
764
|
declare_agent designer "UI / UX implementation. Visual components, design tokens, accessibility." sonnet
|
|
691
765
|
declare_agent scribe "Documentation sync after implementation. No code edits." sonnet
|
|
766
|
+
else
|
|
767
|
+
log " (à la carte — the 6 universal role agents skipped)"
|
|
768
|
+
fi
|
|
692
769
|
case ",$RECIPES," in *",self-improvement,"*)
|
|
693
770
|
declare_agent reflector "Reads session trajectories; proposes atomic lesson deltas for human approval. No code, no auto-apply." opus ;;
|
|
694
771
|
esac
|
|
@@ -699,7 +776,9 @@ fi
|
|
|
699
776
|
# ----- step 3: recipes (opt-in) ------------------------------------------
|
|
700
777
|
|
|
701
778
|
log "Step 3/6: recipes (opt-in) → .claude/rules/"
|
|
779
|
+
RECIPES_EMITTED=0
|
|
702
780
|
if [ -n "$RECIPES" ]; then
|
|
781
|
+
mkdir_if_real "$TARGET_ABS/.claude/rules"
|
|
703
782
|
IFS=',' read -ra RECIPE_LIST <<< "$RECIPES"
|
|
704
783
|
for r in "${RECIPE_LIST[@]}"; do
|
|
705
784
|
src="$CORE_ROOT/recipes/$r.md"
|
|
@@ -711,20 +790,71 @@ if [ -n "$RECIPES" ]; then
|
|
|
711
790
|
backup_and_remember "$dest"
|
|
712
791
|
copy_with_paths_frontmatter "$src" "$dest" "**"
|
|
713
792
|
record_emit ".claude/rules/$r.md" "core/recipes/$r.md" "$MANIFEST_LAST_BACKUP"
|
|
793
|
+
RECIPES_EMITTED=$((RECIPES_EMITTED + 1))
|
|
714
794
|
done
|
|
715
795
|
else
|
|
716
796
|
log " (no recipes selected — pass --recipes=name1,name2 to install)"
|
|
717
797
|
fi
|
|
798
|
+
if [ "$MODE" = "recipes-only" ] && [ "${RECIPES_EMITTED:-0}" -eq 0 ] && [ "$DRY_RUN" != "true" ]; then
|
|
799
|
+
echo "Error: --mode=recipes-only resolved ZERO valid recipes from '--recipes=$RECIPES' — nothing to install (check the names)." >&2
|
|
800
|
+
/bin/rm -f "$MANIFEST_STAGE_PATH"
|
|
801
|
+
exit 1
|
|
802
|
+
fi
|
|
718
803
|
|
|
719
804
|
# ----- step 4: hooks + settings.json -------------------------------------
|
|
720
805
|
|
|
806
|
+
INSTALLED_HOOKS=()
|
|
807
|
+
|
|
808
|
+
if [ "$MODE" = "minimal" ]; then
|
|
809
|
+
log "Step 4/6: hooks + settings.json — skipped (--mode=minimal ships text only)"
|
|
810
|
+
elif [ "$MODE" = "recipes-only" ] || [ "$MODE" = "reflector-only" ]; then
|
|
811
|
+
# À la carte: only the Reflector's trajectory hook (when self-improvement is selected).
|
|
812
|
+
case ",$RECIPES," in
|
|
813
|
+
*",self-improvement,"*)
|
|
814
|
+
log "Step 4/6: hooks — à la carte: stop-trajectory-log only (--mode=$MODE)"
|
|
815
|
+
mkdir_if_real "$TARGET_ABS/.claude/hooks"
|
|
816
|
+
src="$CORE_ROOT/hooks/stop-trajectory-log.sh.template"
|
|
817
|
+
dest="$TARGET_ABS/.claude/hooks/stop-trajectory-log.sh"
|
|
818
|
+
if [ -f "$src" ]; then
|
|
819
|
+
backup_and_remember "$dest"
|
|
820
|
+
substitute_template "$src" "$dest"
|
|
821
|
+
record_emit ".claude/hooks/stop-trajectory-log.sh" "core/hooks/stop-trajectory-log.sh.template" "$MANIFEST_LAST_BACKUP"
|
|
822
|
+
fi
|
|
823
|
+
SETTINGS_PATH="$TARGET_ABS/.claude/settings.json"
|
|
824
|
+
if [ -f "$SETTINGS_PATH" ]; then
|
|
825
|
+
log " $SETTINGS_PATH exists — add the Stop hook manually: \"\$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-trajectory-log.sh"
|
|
826
|
+
elif [ "$DRY_RUN" = "true" ]; then
|
|
827
|
+
log "would write minimal $SETTINGS_PATH (trajectory Stop hook only)"
|
|
828
|
+
else
|
|
829
|
+
/bin/cat > "$SETTINGS_PATH" <<'MINSETTINGS_EOF'
|
|
830
|
+
{
|
|
831
|
+
"$comment": "Minimal project settings generated by CONDUCTOR (à-la-carte mode): registers only the Reflector trajectory Stop hook.",
|
|
832
|
+
"hooks": {
|
|
833
|
+
"Stop": [
|
|
834
|
+
{
|
|
835
|
+
"hooks": [
|
|
836
|
+
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-trajectory-log.sh" }
|
|
837
|
+
]
|
|
838
|
+
}
|
|
839
|
+
]
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
MINSETTINGS_EOF
|
|
843
|
+
log " wrote minimal $SETTINGS_PATH (trajectory Stop hook only)"
|
|
844
|
+
record_emit ".claude/settings.json" "<synthesized:minimal>" ""
|
|
845
|
+
fi
|
|
846
|
+
;;
|
|
847
|
+
*)
|
|
848
|
+
log "Step 4/6: hooks — skipped (--mode=$MODE without self-improvement)"
|
|
849
|
+
;;
|
|
850
|
+
esac
|
|
851
|
+
else
|
|
721
852
|
log "Step 4/6: hooks → .claude/hooks/"
|
|
722
853
|
mkdir_if_real "$TARGET_ABS/.claude/hooks"
|
|
723
854
|
|
|
724
855
|
# Core hooks (always emitted when template exists). Optional hooks (cache-hit baseline, large-file
|
|
725
856
|
# read guard) emit only if their templates are present in the CONDUCTOR core/ tree, allowing the
|
|
726
857
|
# adapter to remain forward-compatible with P1.7 work in progress.
|
|
727
|
-
INSTALLED_HOOKS=()
|
|
728
858
|
for hook in pretool-agent-routing stop-session-log-check stop-r6-review-check stop-cache-hit-baseline-check pretool-large-file-read-guard pretool-commit-current-work-check pretool-commit-test-coverage-check stop-trajectory-log stop-git-hygiene-guard pretool-loop-guard; do
|
|
729
859
|
src="$CORE_ROOT/hooks/$hook.sh.template"
|
|
730
860
|
dest="$TARGET_ABS/.claude/hooks/$hook.sh"
|
|
@@ -821,6 +951,7 @@ SETTINGS_EOF
|
|
|
821
951
|
log " wrote $SETTINGS_PATH ($(printf '%s' "${INSTALLED_HOOKS[*]}" | /usr/bin/wc -w | /usr/bin/tr -d ' ') hook(s) installed in .claude/hooks; settings.json registers 10 core hooks: 5 PreToolUse + 5 Stop)"
|
|
822
952
|
record_emit ".claude/settings.json" "<synthesized>" ""
|
|
823
953
|
fi
|
|
954
|
+
fi
|
|
824
955
|
|
|
825
956
|
# ----- step 4.5: hookify rule templates ----------------------------------
|
|
826
957
|
#
|
|
@@ -833,7 +964,9 @@ fi
|
|
|
833
964
|
# Forward-compat: silent skip if the hookify-templates directory is empty or missing.
|
|
834
965
|
|
|
835
966
|
HOOKIFY_TEMPLATE_DIR="$CONDUCTOR_ROOT/adapters/claude/hookify-templates"
|
|
836
|
-
if [
|
|
967
|
+
if [ "$MODE" != "full" ] && [ "$MODE" != "strict" ]; then
|
|
968
|
+
log "Step 4.5/6: hookify rules — skipped (--mode=$MODE)"
|
|
969
|
+
elif [ -d "$HOOKIFY_TEMPLATE_DIR" ]; then
|
|
837
970
|
log "Step 4.5/6: hookify rules → .claude/hookify.*.local.md"
|
|
838
971
|
HOOKIFY_INSTALLED=0
|
|
839
972
|
HOOKIFY_SKIPPED=0
|
|
@@ -866,7 +999,13 @@ if [ -d "$HOOKIFY_TEMPLATE_DIR" ]; then
|
|
|
866
999
|
fi
|
|
867
1000
|
|
|
868
1001
|
# ---- Step 4.6: self-improvement runtime artifacts (only when recipe selected) ----
|
|
869
|
-
|
|
1002
|
+
if [ "$MODE" = "minimal" ]; then
|
|
1003
|
+
RECIPES_FOR_RUNTIME=""
|
|
1004
|
+
log "Step 4.6: self-improvement runtime — skipped (--mode=minimal ships text only)"
|
|
1005
|
+
else
|
|
1006
|
+
RECIPES_FOR_RUNTIME="$RECIPES"
|
|
1007
|
+
fi
|
|
1008
|
+
case ",$RECIPES_FOR_RUNTIME," in
|
|
870
1009
|
*",self-improvement,"*)
|
|
871
1010
|
log "Step 4.6: emitting self-improvement runtime (prune script + /reflect command)"
|
|
872
1011
|
# prune script → .conductor/reflect/prune-lessons.sh
|
|
@@ -929,6 +1068,9 @@ esac
|
|
|
929
1068
|
|
|
930
1069
|
# ----- step 5: docs templates --------------------------------------------
|
|
931
1070
|
|
|
1071
|
+
if [ "$MODE" = "recipes-only" ] || [ "$MODE" = "reflector-only" ]; then
|
|
1072
|
+
log "Step 5/6: docs templates — skipped (--mode=$MODE is à la carte)"
|
|
1073
|
+
else
|
|
932
1074
|
log "Step 5/6: docs templates → docs/"
|
|
933
1075
|
mkdir_if_real "$TARGET_ABS/docs"
|
|
934
1076
|
mkdir_if_real "$TARGET_ABS/docs/specs"
|
|
@@ -962,8 +1104,13 @@ if [ -f "$CORE_ROOT/docs-templates/specs/_example.md" ]; then
|
|
|
962
1104
|
fi
|
|
963
1105
|
fi
|
|
964
1106
|
|
|
1107
|
+
fi
|
|
1108
|
+
|
|
965
1109
|
# ----- step 6: synthesize CLAUDE.md --------------------------------------
|
|
966
1110
|
|
|
1111
|
+
if [ "$MODE" = "recipes-only" ] || [ "$MODE" = "reflector-only" ]; then
|
|
1112
|
+
log "Step 6/6: CLAUDE.md — skipped (--mode=$MODE is à la carte)"
|
|
1113
|
+
else
|
|
967
1114
|
log "Step 6/6: synthesize CLAUDE.md"
|
|
968
1115
|
CLAUDE_MD="$TARGET_ABS/CLAUDE.md"
|
|
969
1116
|
|
|
@@ -1050,6 +1197,8 @@ else
|
|
|
1050
1197
|
fi
|
|
1051
1198
|
|
|
1052
1199
|
# Finalize manifest now that all emits are complete (before optional baseline measurement).
|
|
1200
|
+
fi
|
|
1201
|
+
|
|
1053
1202
|
finalize_manifest
|
|
1054
1203
|
|
|
1055
1204
|
# ----- step 7 (optional): baseline measurement ---------------------------
|
|
@@ -1157,20 +1306,35 @@ echo ""
|
|
|
1157
1306
|
echo "========================================================"
|
|
1158
1307
|
echo " Done."
|
|
1159
1308
|
echo " Target: $TARGET_ABS"
|
|
1160
|
-
echo "
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1309
|
+
echo " Mode: $MODE"
|
|
1310
|
+
if [ "$MODE" = "recipes-only" ] || [ "$MODE" = "reflector-only" ]; then
|
|
1311
|
+
echo " Universal rules: 0 (à la carte)"
|
|
1312
|
+
case ",$RECIPES," in
|
|
1313
|
+
*",self-improvement,"*) echo " Roles: 1 (reflector only)" ;;
|
|
1314
|
+
*) echo " Roles: 0" ;;
|
|
1315
|
+
esac
|
|
1316
|
+
else
|
|
1317
|
+
echo " Universal rules: 5"
|
|
1318
|
+
if [ "$MODE" = "minimal" ]; then
|
|
1319
|
+
echo " Roles: 0 (--mode=minimal)"
|
|
1320
|
+
else
|
|
1321
|
+
case ",$RECIPES," in
|
|
1322
|
+
*",self-improvement,"*) echo " Roles: 7 (incl. reflector)" ;;
|
|
1323
|
+
*) echo " Roles: 6" ;;
|
|
1324
|
+
esac
|
|
1325
|
+
fi
|
|
1326
|
+
fi
|
|
1165
1327
|
echo " Recipes installed: ${RECIPES:-(none)}"
|
|
1166
1328
|
echo " Hooks: ${#INSTALLED_HOOKS[@]} (${INSTALLED_HOOKS[*]:-none})"
|
|
1167
|
-
|
|
1329
|
+
if [ -f "$TARGET_ABS/.claude/settings.json" ]; then
|
|
1330
|
+
echo " Settings: .claude/settings.json (permissions allowlist + hooks registry)"
|
|
1331
|
+
fi
|
|
1168
1332
|
echo ""
|
|
1169
1333
|
echo " Run \`claude\` (Claude Code restart) to activate new rules."
|
|
1170
1334
|
echo "========================================================"
|
|
1171
1335
|
echo ""
|
|
1172
1336
|
echo "Next steps for the project:"
|
|
1173
1337
|
echo " 1. Open $TARGET_ABS in Claude Code."
|
|
1174
|
-
echo " 2. Edit docs/CURRENT_WORK.md with your project's current state."
|
|
1338
|
+
[ -d "$TARGET_ABS/docs" ] && echo " 2. Edit docs/CURRENT_WORK.md with your project's current state."
|
|
1175
1339
|
echo " 3. Edit CLAUDE.md if you have project-specific orchestrator rules to add."
|
|
1176
1340
|
echo " 4. Verify hook installation: ls -la $TARGET_ABS/.claude/hooks/"
|
package/adapters/codex/README.md
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
# Adapter — Codex (
|
|
1
|
+
# Adapter — Codex (T2)
|
|
2
2
|
|
|
3
|
-
OpenAI Codex (the modern shell-driven agent — not the deprecated original Codex API) is a
|
|
3
|
+
OpenAI Codex (the modern shell-driven agent — not the deprecated original Codex API) is a T2 target because:
|
|
4
4
|
|
|
5
|
-
- It supports a single project rules file at `AGENTS.md` (project root — the established cross-agent convention).
|
|
6
|
-
- It excels at shell-driven scripting and
|
|
5
|
+
- It supports a single project rules file at `AGENTS.md` (project root — the established cross-agent convention), auto-loaded on session start.
|
|
6
|
+
- It excels at shell-driven scripting and agentic terminal work.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
**Tool capability vs CONDUCTOR emission (ADR-031):** as of 2026 Codex ships hooks (default-on), sub-agent dispatch, custom agents, per-task model routing, commands, and built-in managed memory. What is limited today is what CONDUCTOR **emits** for it — rule text + docs + the opt-in Reflector loop; the enforcement guard hooks, role agents, and model-routing config are Phase-2 emission (ADR-034). That is a CONDUCTOR gap, not a Codex limitation. Real tool-side caveat: rules scope by nested-file hierarchy, not glob — the adapter bundles everything into one `AGENTS.md`.
|
|
9
9
|
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
- ❌ No per-call model routing.
|
|
14
|
-
- ❌ No built-in memory directory.
|
|
15
|
-
- ⚠️ Limited multi-step orchestration capability vs Claude/Cursor.
|
|
10
|
+
**Tier**: T2 (see `docs/COMPATIBILITY-MATRIX.md`). Live-verified via the automated headless probe (`tools/live-verify.sh` — current status in `docs/ADAPTER-LIVE-VERIFICATION.md`).
|
|
11
|
+
|
|
12
|
+
> Enumerable facts about this adapter (output paths / tier / capabilities / live verification / headless CLI) are machine-readable in [`metadata.json`](./metadata.json) and CI-checked against `transform.sh` + the validator (ADR-040).
|
|
16
13
|
|
|
17
|
-
**Tier**: T3 — Basic. Rule TEXT installs but most CONDUCTOR mechanism doesn't apply.
|
|
18
14
|
|
|
19
15
|
## Installation path
|
|
20
16
|
|
|
@@ -39,37 +35,37 @@ bash adapters/codex/transform.sh <target> --uninstall # revert (man
|
|
|
39
35
|
└── specs/_example.md
|
|
40
36
|
```
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
- `--recipes=self-improvement` additionally emits the Reflector loop: session-end trajectory hook config (`.codex/hooks.json`), `/reflect` command, reflector agent, prune script, and the `.conductor/reflect/` weekly runner (ADR-032/033).
|
|
39
|
+
|
|
40
|
+
## Native features supported (emitted today)
|
|
43
41
|
|
|
44
42
|
- ✅ Always-loaded baseline (`AGENTS.md`).
|
|
45
43
|
- ✅ All universal rule TEXT.
|
|
46
44
|
- ✅ All doc templates.
|
|
45
|
+
- ✅ Reflector loop (opt-in recipe).
|
|
47
46
|
- ✅ Strong shell-task execution (Codex's primary strength).
|
|
48
47
|
|
|
49
|
-
##
|
|
48
|
+
## Not emitted yet (Phase 2 — Codex supports these natively, ADR-031/034)
|
|
50
49
|
|
|
51
|
-
| Feature |
|
|
50
|
+
| Feature | Interim workaround |
|
|
52
51
|
|---|---|
|
|
53
|
-
| Per-pattern rule scoping | All rules always-loaded. |
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
| Per-call model
|
|
57
|
-
|
|
|
58
|
-
| Multi-step orchestration | Limited — Codex shines at one-shot shell tasks. For multi-step, use Claude/Cursor. |
|
|
52
|
+
| Per-pattern rule scoping | All rules always-loaded in one `AGENTS.md` (Codex scopes by nested-file hierarchy, not globs). |
|
|
53
|
+
| Enforcement guard hooks | Self-police, or pair with project pre-commit git hooks. Only the Reflector session-end hook is emitted today (`--recipes=self-improvement`). |
|
|
54
|
+
| The 6 role agents (sub-agent dispatch) | Codex has native sub-agents; CONDUCTOR doesn't emit its role definitions for Codex yet. Human plays orchestrator. |
|
|
55
|
+
| Per-call model-routing config | Pick the model per invocation via Codex's own model selection. |
|
|
56
|
+
| 4-type memory pattern | Self-managed at `.memory/` (gitignored); Codex's built-in managed memory is separate. |
|
|
59
57
|
|
|
60
58
|
## Best fit use cases
|
|
61
59
|
|
|
62
|
-
- Shell
|
|
63
|
-
- One-shot file transformations.
|
|
64
|
-
-
|
|
65
|
-
- "Run this command and tell me the output" tasks.
|
|
60
|
+
- Shell-driven agentic work and scripting.
|
|
61
|
+
- One-shot file transformations and quick git operations.
|
|
62
|
+
- Headless automation (`codex exec` — the Reflector weekly runner uses it).
|
|
66
63
|
|
|
67
64
|
## After install — first steps
|
|
68
65
|
|
|
69
66
|
1. Verify Codex reads `AGENTS.md` (auto-loaded from project root on session start).
|
|
70
67
|
2. Customize `AGENTS.md` for your project as needed.
|
|
71
68
|
3. Add `.memory/` to `.gitignore`.
|
|
72
|
-
4. Use Codex for shell tasks; rely on Claude/Cursor for multi-step orchestration.
|
|
73
69
|
|
|
74
70
|
## Quirks / known issues
|
|
75
71
|
|
|
@@ -84,4 +80,4 @@ bash adapters/codex/transform.sh <target> --uninstall # revert (man
|
|
|
84
80
|
- ✅ `SUPPORTED-FEATURES.md`
|
|
85
81
|
- ✅ `transform-spec.md`
|
|
86
82
|
- ✅ `transform.sh` (implemented — single-file `AGENTS.md` bundle, recipes, dry-run, manifest-based uninstall)
|
|
87
|
-
-
|
|
83
|
+
- ✅ Live-verified (auto-probe `tools/live-verify.sh` — see `docs/ADAPTER-LIVE-VERIFICATION.md`)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Single source for enumerable adapter facts (ADR-040). CI asserts transform.sh / validator / matrix agree with this file. Update HERE first; docs follow.",
|
|
3
|
+
"tool": "codex",
|
|
4
|
+
"display_name": "Codex",
|
|
5
|
+
"tier": "T2",
|
|
6
|
+
"outputs": [
|
|
7
|
+
{ "path": "AGENTS.md", "kind": "always_loaded", "validated": true },
|
|
8
|
+
{ "path": "docs/CURRENT_WORK.md", "kind": "docs", "validated": false }
|
|
9
|
+
],
|
|
10
|
+
"reflector_outputs": [
|
|
11
|
+
{ "path": ".codex/hooks.json", "note": "Stop trajectory hook config (recipe-gated)" },
|
|
12
|
+
{ "path": ".conductor/reflect", "note": "runner + brief + scheduling (recipe-gated)" }
|
|
13
|
+
],
|
|
14
|
+
"install": { "ala_carte": "block" },
|
|
15
|
+
"legacy_paths": [".codex/codex.md"],
|
|
16
|
+
"capabilities": {
|
|
17
|
+
"tool_native": {
|
|
18
|
+
"hooks": "yes",
|
|
19
|
+
"sub_agents": "yes",
|
|
20
|
+
"model_routing": "yes",
|
|
21
|
+
"commands": "yes",
|
|
22
|
+
"glob_scoping": "no",
|
|
23
|
+
"scheduler": "local"
|
|
24
|
+
},
|
|
25
|
+
"conductor_emitted": {
|
|
26
|
+
"rules": "full",
|
|
27
|
+
"guard_hooks": "none",
|
|
28
|
+
"reflector_loop": "recipe",
|
|
29
|
+
"role_agents": "none",
|
|
30
|
+
"model_routing": "none"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"live_verification": { "status": "verified", "date": "2026-07-09", "cli": "codex-cli 0.144.0", "note": "headless probe listed 4/5 rules + read-CURRENT_WORK-first" },
|
|
34
|
+
"headless_cli": { "command": "codex", "invocation": "codex exec" }
|
|
35
|
+
}
|
|
@@ -41,7 +41,7 @@ adapters/codex/_native/codex.md.tpl # Header template (Codex-flavor
|
|
|
41
41
|
└── specs/_example.md
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
##
|
|
44
|
+
## `AGENTS.md` composition (in order)
|
|
45
45
|
|
|
46
46
|
1. **Header from `_native/codex.md.tpl`** — bilingual (한/영) intro adapted for Codex (one-shot model, shell-task strength).
|
|
47
47
|
2. **ABSOLUTE rules section** — R1-R8 minus Claude-only sub-agent enforcement. R-prefix renumbered.
|
|
@@ -60,9 +60,8 @@ Same as Gemini adapter — strip front-matter, concatenate, replace tool-specifi
|
|
|
60
60
|
|
|
61
61
|
| Case | Adapter behavior |
|
|
62
62
|
|---|---|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
| `.codex/codex.md` exceeds Codex context budget | Warn; document trim strategy in `notes.md`. |
|
|
63
|
+
| Existing `AGENTS.md` | Back up, then write (manifest-tracked; `--uninstall` restores). |
|
|
64
|
+
| `AGENTS.md` exceeds Codex context budget | Warn; document trim strategy in `notes.md`. |
|
|
66
65
|
|
|
67
66
|
## Idempotency check
|
|
68
67
|
|
|
@@ -71,14 +70,14 @@ Re-run reports "SKIP (exists)" for everything.
|
|
|
71
70
|
## Verification commands (P3.5 will fill)
|
|
72
71
|
|
|
73
72
|
```bash
|
|
74
|
-
test -f "<target
|
|
73
|
+
test -f "<target>/AGENTS.md" || echo "MISSING AGENTS.md"
|
|
75
74
|
|
|
76
75
|
# Run Codex in <target>; verify it follows ABSOLUTE rules + universal conventions.
|
|
77
76
|
```
|
|
78
77
|
|
|
79
78
|
## P3.5 Codex version compatibility check
|
|
80
79
|
|
|
81
|
-
- Confirm
|
|
80
|
+
- Confirm `AGENTS.md` IS the canonical project-rules location. (Confirmed — live-verified; current status in `docs/ADAPTER-LIVE-VERIFICATION.md`.)
|
|
82
81
|
- Confirm Codex auto-loads it on session start.
|
|
83
82
|
- Confirm Codex follows the rule TEXT in its inline code generation.
|
|
84
83
|
|