feat(installer): implement MAM skills installer with complete user guide and pass reviewer reviews
This commit is contained in:
@@ -0,0 +1,95 @@
|
|||||||
|
# 🛠️ Multi-Agent Mux (MAM) 설치 및 적용 가이드
|
||||||
|
|
||||||
|
MAM은 단일 워크스페이스 상에서 복수의 에이전트(Claude, Cline, Agy, Hermes 등)들이 서로의 상태를 오염시키지 않고 협업할 수 있도록 프로세스 격리 및 라이프사이클 관리를 제공하는 프레임워크입니다.
|
||||||
|
|
||||||
|
이 가이드는 기존의 다른 프로젝트/레포지토리에 MAM을 신속하게 도입하고 적용하는 절차를 설명합니다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. ⚙️ 사전 요구사항
|
||||||
|
MAM 스킬 및 스크립트들은 호스트 시스템의 다음 도구들에 의존합니다. 설치 전에 확인해 주세요.
|
||||||
|
* **tmux**: 에이전트를 백그라운드 격리 Pane에서 구동하기 위한 프로세스 컨테이너
|
||||||
|
* **python3**: 세션 레지스트리(YAML/SQLite DB) 파싱 및 유효성 검사
|
||||||
|
* **sqlite3**: 트랜잭션 안전성 및 오케스트레이션 락 보장
|
||||||
|
* **rsync**: `.agents/` 오케스트레이터 및 스킬 폴더 복제 및 동기화
|
||||||
|
* **python3-yaml (pyyaml)**: 세션 데이터 YAML 저장 및 로드 의존성 (`pip install pyyaml`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 🚀 자동 설치 방법
|
||||||
|
|
||||||
|
MAM의 자동 설치 스크립트(`install_mam.sh`)를 사용하여 10초 만에 필요한 규칙과 라이프사이클 툴킷을 타겟 프로젝트에 이식할 수 있습니다.
|
||||||
|
|
||||||
|
### 설치 스크립트 실행
|
||||||
|
MAM 레포지토리 루트에서 다음 명령어를 실행합니다.
|
||||||
|
```bash
|
||||||
|
# 기본 사용법 (타겟 프로젝트 경로 지정)
|
||||||
|
$ bash scripts/install_mam.sh --target /path/to/your/project
|
||||||
|
|
||||||
|
# 만약 이미 타겟에 AGENTS.md 가 존재하여 강제로 덮어쓰고 싶다면:
|
||||||
|
$ bash scripts/install_mam.sh --target /path/to/your/project --force
|
||||||
|
```
|
||||||
|
|
||||||
|
### 설치 스크립트가 수행하는 작업:
|
||||||
|
1. **의존성 진단**: 시스템에 `tmux`, `python3`, `sqlite3` 가 설치되어 있는지 확인합니다.
|
||||||
|
2. **규칙 및 스킬 복제**: 오케스트레이션 가이드(`.agents/` 하위 전체)를 타겟 프로젝트 하위로 이식합니다.
|
||||||
|
3. **지침 전파**: 에이전트가 로드하고 복종할 행동 지침 문서(`AGENTS.md`)를 프로젝트 루트에 복사합니다.
|
||||||
|
4. **형상 제외 설정**: 세션 DB 및 격리 캐시 저장소인 `.mam/` 디렉토리를 타겟 프로젝트의 `.gitignore` 에 자동 주입하여 불필요한 형상 관리를 방지합니다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 🎯 핵심 사용 워크플로우 (Quick Start)
|
||||||
|
|
||||||
|
설치가 완료되면, 타겟 프로젝트 루트에서 에이전트들을 기동 및 관리할 수 있습니다.
|
||||||
|
|
||||||
|
### 1) 에이전트 격리 세션 생성 (Create)
|
||||||
|
새로운 에이전트를 독립된 격리 가상 디렉토리에서 띄웁니다.
|
||||||
|
```bash
|
||||||
|
$ bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh \
|
||||||
|
--workspace "/path/to/your/project" \
|
||||||
|
--agent claude \
|
||||||
|
--role developer \
|
||||||
|
--session my-project-dev-claude \
|
||||||
|
--isolate
|
||||||
|
```
|
||||||
|
* `--isolate` 옵션을 주면 `.mam/agent_homes/<uuid>/` 하위에 로그인 및 설정은 유지하되 대화 내역은 격리되는 홈이 형성됩니다.
|
||||||
|
|
||||||
|
### 2) 세션 접속 (Attach)
|
||||||
|
백그라운드에서 구동된 에이전트 TUI 화면에 들어갑니다. (MAM은 독립 격리 tmux 서버인 `-L multi-agent-mux` 를 경유해야 합니다.)
|
||||||
|
```bash
|
||||||
|
$ tmux -L multi-agent-mux attach -t my-project-dev-claude
|
||||||
|
```
|
||||||
|
* **화면 탈출**: 대화 중 세션을 유지한 채 터미널로 돌아오려면 `Ctrl + B`를 누른 뒤 `D` 키를 차례로 입력합니다.
|
||||||
|
|
||||||
|
### 3) 에이전트 상태 복원 (Resume)
|
||||||
|
세션이 중지되었거나, 호스트 재기동으로 tmux가 소멸한 경우에도 이전 대화 ID 및 격리 디렉토리를 원자적으로 이어받아 다시 기동할 수 있습니다.
|
||||||
|
```bash
|
||||||
|
# 1단계: resume/SKILL.md를 참고하여 복원 스크립트 실행 (YAML/DB의 UUID 자동 로드 및 T4 격리 재바인딩)
|
||||||
|
$ WORKSPACE="/path/to/your/project"
|
||||||
|
$ AGENT="claude"
|
||||||
|
$ SESSION_NAME="my-project-dev-claude"
|
||||||
|
|
||||||
|
$ UUID=$(bash .agents/skills/multi-agent-mux-resume/scripts/resolve_session_id.sh \
|
||||||
|
--workspace "$WORKSPACE" --agent "$AGENT" --session "$SESSION_NAME")
|
||||||
|
|
||||||
|
# 2단계: 동적 격리 인자 주입 스폰 수행 후 레지스트리 상태 running 복구
|
||||||
|
# (상세 쉘 명령어는 .agents/skills/multi-agent-mux-resume/SKILL.md 참조)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4) 세션 종료 및 정리 (Stop / Purge)
|
||||||
|
세션을 정지시키고 대화 컨텍스트를 동결하거나(default), 완전히 소멸시킵니다(`--purge-conversation`).
|
||||||
|
```bash
|
||||||
|
# 대화 메타데이터를 백업 및 영속화하고, 안전하게 종료 (status=stopped)
|
||||||
|
$ bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh \
|
||||||
|
--session my-project-dev-claude --agent claude
|
||||||
|
|
||||||
|
# 대화 내용 및 격리 홈 디렉토리를 완전히 청소하고 종료 (status=terminated, resumable=false)
|
||||||
|
$ bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh \
|
||||||
|
--session my-project-dev-claude --agent claude --purge-conversation --yes
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛡️ 협업 및 보안 가이드라인
|
||||||
|
* MAM을 사용할 때 모든 에이전트(개발자, 리뷰어)들은 루트의 `AGENTS.md` 지침을 우선 숙지하도록 설계해야 오탐과 무분별한 리팩토링 범람을 방지할 수 있습니다.
|
||||||
|
* 각 에이전트 역할별로 리뷰 프로세스를 돌릴 시, 승인 결과 보고서(.md)는 `.mam/reports/<session_name>/` 하위에 생성 및 형상 커밋하는 규약(`.agents/MULTI_AGENT_RULES.md`)을 준수해 주세요.
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
# Review Report (Re-review) — MAM Installer (`scripts/install_mam.sh`) & Manual (`.agents/INSTALL.md`)
|
||||||
|
|
||||||
|
- **Reviewer**: Reviewer Cline (`canary-projects-multi-agent-mux-reviewer-cline`, role: reviewer)
|
||||||
|
- **Date**: 2026-07-11 (re-review after D1/D2/D3 remediation)
|
||||||
|
- **Previous report**: `report-mam-installer-review.md` (verdict: NOT PASS)
|
||||||
|
- **Files reviewed**: `scripts/install_mam.sh` (untracked, new), `.agents/INSTALL.md` (untracked, new)
|
||||||
|
- **Governing documents**: `AGENTS.md`, `.agents/MULTI_AGENT_RULES.md` / `.ko.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verdict: **PASS** ✅
|
||||||
|
|
||||||
|
All three previously-blocking defects (D1 undeclared `rsync` dependency, D2 `__pycache__/`+`.pyc` leak, D3 symlink source mis-resolution) are resolved and verified in-session. The installer now passes `bash -n`, `shellcheck` (clean), a symlink-invocation source-resolution test, an rsync dry-run leak check, and a full end-to-end install into a scratch target. It conforms to `AGENTS.md` and `MULTI_AGENT_RULES.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Remediation Verification (all three defects)
|
||||||
|
|
||||||
|
### D1 — `rsync` undeclared dependency → RESOLVED ✅
|
||||||
|
**Fix**: `DEPS=(tmux python3 sqlite3 rsync)` (line 80) — `rsync` now in the declared dependency list. `.agents/INSTALL.md` §1 line 14 documents `rsync` as a prerequisite.
|
||||||
|
**In-session verification**: Running the installer in a sandbox missing `sqlite3` produced a clean `[ERROR] Missing required dependencies: sqlite3` and exited 1 **before** touching the target — no partial `.agents/` created (post-install checks confirmed `.agents/`, `.gitignore`, and `AGENTS.md` all absent). This proves the D1 fix makes the "Dependency checks completed" gate (line 99) truthful: the script no longer proceeds past the check while a hard dependency is missing.
|
||||||
|
|
||||||
|
### D2 — `__pycache__/`+`.pyc` leak → RESOLVED ✅
|
||||||
|
**Fix**: rsync invocation (line 107) now includes `--exclude='__pycache__/' --exclude='*.pyc'`.
|
||||||
|
**In-session verification**: rsync dry-run with the updated exclude list returned `PycACHE_LEAK_NONE`. Full end-to-end install `find /tmp/.../.agents -name '__pycache__' -o -name '*.pyc'` returned nothing. The target is no longer polluted with host-specific bytecode caches.
|
||||||
|
|
||||||
|
### D3 — Symlink source mis-resolution → RESOLVED ✅
|
||||||
|
**Fix**: lines 60–67 — a `while [ -h "$SOURCE" ]` readlink loop tracks symlinks back to the original script, with relative-symlink handling (`[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"`).
|
||||||
|
**In-session verification**: I symlinked the installer to `/tmp/mam_install_symlinked.sh` and ran the resolution loop; it resolved `SRC_DIR=/home/godopu16/PuKi/laa/canary_projects/multi-agent-mux` (correct), printing `SYMLINK_RESOLVE_PASS`. The previous failure (resolving to `/`) is gone.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Full Validation Suite (Re-run)
|
||||||
|
|
||||||
|
| Check | Command | Result |
|
||||||
|
|-------|---------|--------|
|
||||||
|
| Syntax | `bash -n scripts/install_mam.sh` | ✅ `BASH_N_OK` |
|
||||||
|
| Lint | `shellcheck -f gcc scripts/install_mam.sh` | ✅ `SHELLCHECK_CLEAN` (0 findings) |
|
||||||
|
| D3 symlink resolve | loop on `/tmp/...symlinked.sh` | ✅ `SRC_DIR=.../multi-agent-mux` (`SYMLINK_RESOLVE_PASS`) |
|
||||||
|
| D2 leak dry-run | `rsync --dry-run ... \| grep __pycache__` | ✅ `PycACHE_LEAK_NONE` |
|
||||||
|
| D1 dep-gate abort | install with `sqlite3` missing | ✅ clean abort, no partial install |
|
||||||
|
| End-to-end install | `install_mam.sh --target /tmp/...` | ✅ completes; `INSTALL_MD_PRESENT`, `GITIGNORE_PRESENT`, `AGENTS_MD_PRESENT`, `PYCACHE_LEAK_CHECK_DONE` (no leaks) |
|
||||||
|
| `INSTALL.md` rsync doc | `grep -n rsync .agents/INSTALL.md` | ✅ line 14 documents `rsync` |
|
||||||
+156
@@ -0,0 +1,156 @@
|
|||||||
|
# Review Report — MAM Installer (`scripts/install_mam.sh`) & Manual (`.agents/INSTALL.md`)
|
||||||
|
|
||||||
|
- **Reviewer**: Reviewer Cline (`canary-projects-multi-agent-mux-reviewer-cline`, role: reviewer)
|
||||||
|
- **Date**: 2026-07-11
|
||||||
|
- **Files reviewed**: `scripts/install_mam.sh` (untracked, new), `.agents/INSTALL.md` (untracked, new)
|
||||||
|
- **Governing documents**: `AGENTS.md`, `.agents/MULTI_AGENT_RULES.md` / `.ko.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verdict: **NOT PASS** ❌
|
||||||
|
|
||||||
|
The script passes its claimed static checks (`bash -n` ✅, `shellcheck` clean ✅) and the manual is well-structured. However, three robustness defects cause the installer to break its own documented success criteria on systems lacking `rsync`, to pollute the target project with host Python bytecode caches, and to mis-resolve its source directory when invoked via symlink. These contradict `AGENTS.md` §4 (Goal-Driven Execution: "Define success criteria. Loop until verified") and §1 (Think Before Coding: "Surface tradeoffs... if unclear, ask"). They are straightforward to fix; this is a *NOT PASS with clear remediation*, not a fundamental design rejection.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Validation Commands Run In-Session
|
||||||
|
|
||||||
|
| Check | Command | Result |
|
||||||
|
|-------|---------|--------|
|
||||||
|
| Syntax | `bash -n scripts/install_mam.sh` | ✅ `BASH_N_OK` |
|
||||||
|
| Lint | `shellcheck -f gcc scripts/install_mam.sh` | ✅ clean (0 findings) |
|
||||||
|
| Git state | `git status --short scripts/install_mam.sh .agents/INSTALL.md` | both untracked (`??`) |
|
||||||
|
| Target creation | `mkdir -p <nonexistent> && cd && pwd` | ✅ works under `set -euo pipefail` |
|
||||||
|
| rsync dry-run | `rsync -a --dry-run --out-format='%n' --exclude=...` | ⚠️ reveals `__pycache__/`+`.pyc` leak |
|
||||||
|
| Symlink resolution | `cd "$(dirname "/tmp/symlinked.sh")/.."` | ❌ resolves to `/` (wrong source) |
|
||||||
|
| `.gitignore` idempotency | `grep -Fqx "$MAM_PATTERN"` in `if` | ✅ `set -e`-safe (conditional context) |
|
||||||
|
| `INSTALL.md` inclusion | dry-run file list | ✅ `INSTALL.md` is copied |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Defects Found (blocking)
|
||||||
|
|
||||||
|
### D1 — `rsync` is an undeclared hard dependency (MEDIUM)
|
||||||
|
|
||||||
|
**Location**: `scripts/install_mam.sh:100`
|
||||||
|
```bash
|
||||||
|
rsync -a --exclude='.git/' --exclude='reports/' --exclude='*.log' "$SRC_DIR/.agents/" "$TARGET_DIR/.agents/"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problem**: `rsync` is invoked as the core copy mechanism, but it is absent from:
|
||||||
|
- The script's `DEPS` array (line 73: `DEPS=(tmux python3 sqlite3)` — no `rsync`)
|
||||||
|
- `.agents/INSTALL.md` §1 prerequisite list (tmux, python3, sqlite3, pyyaml — no rsync)
|
||||||
|
|
||||||
|
**Impact**: On a system without `rsync` (e.g. minimal containers, some Alpine images, WSL defaults), under `set -euo pipefail` the script aborts at line 100 with an unhelpful `rsync: command not found` — **after** `mkdir -p "$TARGET_DIR/.agents"` (line 96) has already partially created the target tree. The user is left with a half-installed `.agents/` and no guidance from the dependency-check stage (which already printed `[OK] Dependency checks completed.`).
|
||||||
|
|
||||||
|
**Why it violates the guidelines**:
|
||||||
|
- `AGENTS.md` §4 Goal-Driven: the stated success criterion "Dependency checks completed" (line 92) is *false* when `rsync` is missing — the verification loop is incomplete.
|
||||||
|
- `AGENTS.md` §1 Think Before Coding: an undocumented external dependency is exactly the kind of "hidden confusion" the guideline warns against.
|
||||||
|
|
||||||
|
**Required fix**:
|
||||||
|
```bash
|
||||||
|
# Line 73 — add rsync to the declared dependency list
|
||||||
|
DEPS=(tmux python3 sqlite3 rsync)
|
||||||
|
```
|
||||||
|
And mirror in `.agents/INSTALL.md` §1: add `**rsync**: install_mam.sh .agents/ 폴더 동기화에 사용`.
|
||||||
|
|
||||||
|
### D2 — `__pycache__/` + `.pyc` bytecode caches leak into the target (MEDIUM)
|
||||||
|
|
||||||
|
**Location**: `scripts/install_mam.sh:100`
|
||||||
|
|
||||||
|
**Problem**: The rsync exclude list does **not** exclude Python bytecode caches. Dry-run output confirms these files are copied into the target:
|
||||||
|
```
|
||||||
|
skills/multi-agent-mux-delegate-job/scripts/__pycache__/job_subscriber.cpython-314.pyc
|
||||||
|
... (4 .pyc files total)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Impact**: The installer pollutes the target with host-specific (CPython-version-stamped) bytecode caches. The source repo already ignores these via root `.gitignore` lines 13–14 (`__pycache__/`, `*.pyc`), but rsync reads the filesystem, not gitignore. The target inherits machine-specific artifacts that may confuse later `python3` runs or get accidentally committed.
|
||||||
|
|
||||||
|
**Why it violates**: `AGENTS.md` §2 Simplicity First ("No features beyond what was asked") and §3 Surgical Changes (installer should install, not leak build state).
|
||||||
|
|
||||||
|
**Required fix**:
|
||||||
|
```bash
|
||||||
|
rsync -a --exclude='.git/' --exclude='reports/' --exclude='*.log' \
|
||||||
|
--exclude='__pycache__/' --exclude='*.pyc' \
|
||||||
|
"$SRC_DIR/.agents/" "$TARGET_DIR/.agents/"
|
||||||
|
### D3 — Symlink-invoked source resolution mis-resolves to `/` (MEDIUM)
|
||||||
|
|
||||||
|
**Location**: `scripts/install_mam.sh:60`
|
||||||
|
```bash
|
||||||
|
SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problem**: `${BASH_SOURCE[0]}` returns the *invocation path*, not the resolved real path. When the script is run via a symlink (e.g. `ln -sfn .../install_mam.sh /usr/local/bin/mam-install && mam-install`), `dirname "/usr/local/bin/mam-install"` = `/usr/local/bin`, and `cd /usr/local/bin/..` = `/usr/local`. In my test with a `/tmp` symlink, this resolved to `/` — the script would then look for `/.agents/` (wrong/empty source) and either copy the wrong tree or fail with a confusing "source and target identical" or "no such file" error.
|
||||||
|
|
||||||
|
**Impact**: The documented usage (`bash scripts/install_mam.sh --target ...`) works only when invoked from a real path. Users who symlink the installer into their `PATH` (a common pattern) get silent wrong-source behavior or an obscure failure, with no diagnostic pointing at the symlink issue.
|
||||||
|
|
||||||
|
**Why it violates the guidelines**:
|
||||||
|
- `AGENTS.md` §1 Think Before Coding: a silent wrong-source copy is the kind of hidden confusion the guideline exists to prevent.
|
||||||
|
- `MULTI_AGENT_RULES.md` path-safety: the rest of the framework uses `readlink`-based resolution and explicit path guards; this installer is inconsistent with that norm.
|
||||||
|
|
||||||
|
**Required fix** (Linux; the project's documented platform):
|
||||||
|
```bash
|
||||||
|
SRC_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.." && pwd)"
|
||||||
|
```
|
||||||
|
`readlink -f` is GNU coreutils. If macOS support is required, a portable fallback:
|
||||||
|
```bash
|
||||||
|
src="${BASH_SOURCE[0]}"
|
||||||
|
while [ -L "$src" ]; do src="$(readlink "$src")"; done
|
||||||
|
SRC_DIR="$(cd "$(dirname "$src")/.." && pwd)"
|
||||||
|
```
|
||||||
|
Add `readlink` to `DEPS` if taking the `readlink -f` route.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Conformance to `AGENTS.md`
|
||||||
|
|
||||||
|
| Principle | Assessment |
|
||||||
|
|-----------|------------|
|
||||||
|
| §1 Think Before Coding | ❌ D1/D3 hide undocumented dependencies and a symlink footgun instead of surfacing them. |
|
||||||
|
| §2 Simplicity First | ⚠️ Mostly clean, but D2 ships unrequested bytecode artifacts — a non-minimal side effect. |
|
||||||
|
| §3 Surgical Changes | ✅ No drive-by refactors; existing-user `AGENTS.md` is backed up before overwrite (lines 106–110). |
|
||||||
|
| §4 Goal-Driven Execution | ❌ D1: the "Dependency checks completed" success criterion (line 92) is unverified for `rsync`. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Conformance to `MULTI_AGENT_RULES.md`
|
||||||
|
|
||||||
|
| Rule | Assessment |
|
||||||
|
|------|------------|
|
||||||
|
| `.mam/` under gitignore | ✅ `.gitignore` injection (lines 119–134) is idempotent (`grep -Fqx`), path-safe, scoped to `/.mam/`. |
|
||||||
|
| Path safeguards | ⚠️ The `SRC_DIR == TARGET_DIR` self-install guard (line 66) is good, but D3's symlink mis-resolution can still point `SRC_DIR` at an unexpected location, undermining the guard. |
|
||||||
|
| Markdown collaboration | ✅ `.agents/INSTALL.md` is a proper markdown manual; this report is persisted under `.mam/reports/<session>/`. |
|
||||||
|
| Role isolation | ✅ No cross-role scope creep — this is pure install tooling. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. What's Good (acknowledge correctly done)
|
||||||
|
|
||||||
|
- `set -euo pipefail` at the top — correct strict-mode hygiene.
|
||||||
|
- `SRC_DIR == TARGET_DIR` self-install guard (line 66) — prevents the script from copying onto itself.
|
||||||
|
- `AGENTS.md` backup-before-overwrite with timestamped `.bak.<epoch>` (lines 107–110) — respects existing user files; `--force` is opt-in.
|
||||||
|
- `.gitignore` injection is **idempotent** (the `grep -Fqx` check prevents duplicate appends on re-run) and the `grep` non-zero return is safe under `set -e` because it sits in an `if` conditional.
|
||||||
|
- `INSTALL.md` is clear, Korean-localized, and correctly documents the `--isolate` flag, the `-L multi-agent-mux` tmux server convention, and the resume/purge state machine.
|
||||||
|
- `bash -n` and `shellcheck` claims are **accurate** — I reproduced both.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Remediation Summary (for the developer)
|
||||||
|
|
||||||
|
| ID | Fix | Effort |
|
||||||
|
|----|-----|--------|
|
||||||
|
| D1 | Add `rsync` to `DEPS` array (line 73) and to `INSTALL.md` §1 prereq list | 2 lines |
|
||||||
|
| D2 | Add `--exclude='__pycache__/' --exclude='*.pyc'` to the rsync invocation (line 100) | 1 line |
|
||||||
|
| D3 | Resolve symlinks: `readlink -f "${BASH_SOURCE[0]}"` before `dirname`/`cd` (line 60); add `readlink` to `DEPS` | 1–2 lines |
|
||||||
|
| Re-verify | Re-run `bash -n` + `shellcheck` + a scratch-target dry-run after fixes | — |
|
||||||
|
|
||||||
|
All three are small, surgical edits that trace directly to the defects above. No design rework is needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Final Statement
|
||||||
|
|
||||||
|
The installer's static hygiene is genuine (`bash -n`/`shellcheck` pass as claimed), and the manual is solid. But three robustness defects — an undeclared `rsync` dependency that falsifies the "dependency checks completed" gate, a bytecode-cache leak that pollutes the target, and a symlink source-resolution bug that can silently copy from the wrong directory — mean the installer does not yet meet `AGENTS.md`'s "Goal-Driven Execution" bar (the success criteria are not actually verified) or the "Think Before Coding" bar (hidden failure modes not surfaced). These are fixable in under five lines total.
|
||||||
|
|
||||||
|
**NOT PASS** — return to developer with D1/D2/D3 remediation. Re-review after the three fixes are applied and a scratch-target dry-run confirms no `__pycache__/` leak and a symlink-invoked run resolves the correct `SRC_DIR`.
|
||||||
|
```
|
||||||
Executable
+164
@@ -0,0 +1,164 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ==============================================================================
|
||||||
|
# Multi-Agent Mux (MAM) Skill Installer
|
||||||
|
# Efficiently installs MAM orchestration rules & skills to another project.
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ANSI color codes
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[0;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Helper functions for logs
|
||||||
|
log_info() { echo -e "${BLUE}[INFO]${NC} $*"; }
|
||||||
|
log_ok() { echo -e "${GREEN}[OK]${NC} $*"; }
|
||||||
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||||
|
log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
|
||||||
|
|
||||||
|
show_help() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $0 [options]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-t, --target <path> Target directory/project where MAM should be installed (defaults to current directory)
|
||||||
|
-f, --force Force copy AGENTS.md even if it already exists (backups are still made)
|
||||||
|
-h, --help Show this help message
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
TARGET_DIR="."
|
||||||
|
FORCE=0
|
||||||
|
|
||||||
|
# Parse CLI arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-t|--target)
|
||||||
|
TARGET_DIR="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-f|--force)
|
||||||
|
FORCE=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
show_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_error "Unknown option: $1"
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Resolve absolute path for source and target, tracking symlinks gracefully
|
||||||
|
SOURCE="${BASH_SOURCE[0]}"
|
||||||
|
while [ -h "$SOURCE" ]; do
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
SOURCE="$(readlink "$SOURCE")"
|
||||||
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
|
||||||
|
done
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
SRC_DIR="$(cd "$DIR/.." && pwd)"
|
||||||
|
TARGET_DIR="$(mkdir -p "$TARGET_DIR" && cd "$TARGET_DIR" && pwd)"
|
||||||
|
|
||||||
|
log_info "Installing MAM skills to target project: $TARGET_DIR"
|
||||||
|
log_info "Source directory resolved: $SRC_DIR"
|
||||||
|
|
||||||
|
if [ "$SRC_DIR" = "$TARGET_DIR" ]; then
|
||||||
|
log_error "Source and Target directories are the same! Cannot install to oneself."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. Dependency Checks
|
||||||
|
log_info "Verifying host dependencies..."
|
||||||
|
DEPS=(tmux python3 sqlite3 rsync)
|
||||||
|
MISSING_DEPS=()
|
||||||
|
for dep in "${DEPS[@]}"; do
|
||||||
|
if ! command -v "$dep" &>/dev/null; then
|
||||||
|
MISSING_DEPS+=("$dep")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#MISSING_DEPS[@]} -ne 0 ]; then
|
||||||
|
log_error "Missing required dependencies: ${MISSING_DEPS[*]}"
|
||||||
|
log_error "Please install them before using MAM."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check Python PyYAML library
|
||||||
|
if ! python3 -c "import yaml" &>/dev/null; then
|
||||||
|
log_warn "Python 'pyyaml' package is not installed. Python YAML parsing features may fail."
|
||||||
|
log_warn "Please run: pip install pyyaml"
|
||||||
|
fi
|
||||||
|
log_ok "Dependency checks completed."
|
||||||
|
|
||||||
|
# 2. Copy .agents/ folder
|
||||||
|
log_info "Deploying orchestration rules & skills (.agents/)..."
|
||||||
|
mkdir -p "$TARGET_DIR/.agents"
|
||||||
|
|
||||||
|
# Sync rules and skills, avoiding copying temporary or system files
|
||||||
|
# Exclude git histories or internal runtime cache if any
|
||||||
|
rsync -a --exclude='.git/' --exclude='reports/' --exclude='*.log' --exclude='__pycache__/' --exclude='*.pyc' "$SRC_DIR/.agents/" "$TARGET_DIR/.agents/"
|
||||||
|
log_ok "Deployed Rules and Skills under target's .agents/"
|
||||||
|
|
||||||
|
# 3. Copy AGENTS.md to root
|
||||||
|
log_info "Configuring developer guidelines (AGENTS.md)..."
|
||||||
|
if [ -f "$TARGET_DIR/AGENTS.md" ]; then
|
||||||
|
if [ "$FORCE" -eq 1 ]; then
|
||||||
|
log_warn "AGENTS.md already exists in target project. Backing up and overwriting..."
|
||||||
|
cp "$TARGET_DIR/AGENTS.md" "$TARGET_DIR/AGENTS.md.bak.$(date +%s)"
|
||||||
|
cp "$SRC_DIR/AGENTS.md" "$TARGET_DIR/AGENTS.md"
|
||||||
|
log_ok "Guidelines overwritten successfully."
|
||||||
|
else
|
||||||
|
log_warn "AGENTS.md already exists in target. Skipping copy. Use -f/--force to overwrite."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
cp "$SRC_DIR/AGENTS.md" "$TARGET_DIR/AGENTS.md"
|
||||||
|
log_ok "Guidelines AGENTS.md copied to project root."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. Gitignore adjustments
|
||||||
|
log_info "Registering runtime isolation blocks in .gitignore..."
|
||||||
|
GITIGNORE="$TARGET_DIR/.gitignore"
|
||||||
|
MAM_PATTERN="/.mam/"
|
||||||
|
|
||||||
|
if [ -f "$GITIGNORE" ]; then
|
||||||
|
if grep -Fqx "$MAM_PATTERN" "$GITIGNORE"; then
|
||||||
|
log_ok "/.mam/ already registered in target's .gitignore."
|
||||||
|
else
|
||||||
|
echo -e "\n# Multi-Agent Mux (MAM) runtime databases and isolation cache\n$MAM_PATTERN" >> "$GITIGNORE"
|
||||||
|
log_ok "Appended /.mam/ registration to .gitignore."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "# Multi-Agent Mux (MAM) runtime databases and isolation cache\n$MAM_PATTERN" > "$GITIGNORE"
|
||||||
|
log_ok "Created .gitignore with /.mam/ exclusion."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5. Initialize runtime reports folder
|
||||||
|
mkdir -p "$TARGET_DIR/.mam/reports"
|
||||||
|
log_ok "Initialized runtime structures."
|
||||||
|
|
||||||
|
# Done
|
||||||
|
log_ok "MAM Installation completed successfully!"
|
||||||
|
cat <<EOF
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
💡 Quick Start Guide:
|
||||||
|
1. Initialize a new isolated session:
|
||||||
|
$ bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh \\
|
||||||
|
--workspace "$TARGET_DIR" --agent claude --role developer --isolate
|
||||||
|
|
||||||
|
2. Attach to the running session:
|
||||||
|
$ tmux -L multi-agent-mux attach -t <session_name>
|
||||||
|
|
||||||
|
3. Gracefully stop the session:
|
||||||
|
$ bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh \\
|
||||||
|
--session <session_name> --agent claude
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
EOF
|
||||||
Reference in New Issue
Block a user