Add portable Codex ops kit

This commit is contained in:
slaguru666
2026-04-12 14:00:55 +01:00
commit aa907983db
19 changed files with 679 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -euo pipefail
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
if [[ ! -d "$CODEX_HOME" ]]; then
echo "Codex home not found: $CODEX_HOME" >&2
exit 1
fi
echo "Codex home: $CODEX_HOME"
echo
echo "Top-level sizes"
du -sh "$CODEX_HOME"/* "$CODEX_HOME"/.[!.]* 2>/dev/null | sort -h
echo
echo "Large session files"
python3 - "$CODEX_HOME" <<'PY'
from pathlib import Path
import sys
root = Path(sys.argv[1]) / "sessions"
files = sorted((p for p in root.rglob("*.jsonl") if p.is_file()), key=lambda p: p.stat().st_size, reverse=True)
print(f"session files: {len(files)}")
for path in files[:10]:
size_mb = path.stat().st_size / (1024 * 1024)
print(f"{size_mb:9.1f} MB {path}")
PY
echo
echo "Config snapshot"
sed -n '1,220p' "$CODEX_HOME/config.toml" 2>/dev/null || true
echo
echo "Memory markdown files"
find "$CODEX_HOME/memories" -type f -name '*.md' 2>/dev/null | sort || true
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DEST="${1:-$HOME/Documents/codex-ops-kit}"
rm -rf "$DEST"
mkdir -p "$DEST"
copy_path() {
local rel="$1"
local src="$REPO_ROOT/$rel"
local dest="$DEST/$rel"
mkdir -p "$(dirname "$dest")"
cp -R "$src" "$dest"
}
copy_path README.md
copy_path AGENTS.md
copy_path .gitignore
copy_path docs
copy_path memory
copy_path templates
copy_path scripts
find "$DEST/scripts" -name '__pycache__' -type d -prune -exec rm -rf {} +
find "$DEST" -name '*.pyc' -delete
echo "Created clean shareable repo at: $DEST"
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
STAMP="$(date +%Y%m%d-%H%M%S)"
DEST="${1:-$REPO_ROOT/export/codex-portable-$STAMP}"
mkdir -p "$DEST"
mkdir -p "$DEST/codex-home"
copy_if_exists() {
local src="$1"
local dest="$2"
if [[ -e "$src" ]]; then
mkdir -p "$(dirname "$dest")"
cp -R "$src" "$dest"
fi
}
copy_if_exists "$CODEX_HOME/config.toml" "$DEST/codex-home/config.toml"
copy_if_exists "$CODEX_HOME/AGENTS.md" "$DEST/codex-home/AGENTS.md"
copy_if_exists "$CODEX_HOME/memories" "$DEST/codex-home/memories"
copy_if_exists "$CODEX_HOME/rules" "$DEST/codex-home/rules"
copy_if_exists "$REPO_ROOT/templates" "$DEST/templates"
copy_if_exists "$REPO_ROOT/memory" "$DEST/memory"
copy_if_exists "$REPO_ROOT/scripts" "$DEST/scripts"
copy_if_exists "$REPO_ROOT/docs" "$DEST/docs"
copy_if_exists "$REPO_ROOT/README.md" "$DEST/README.md"
cat > "$DEST/EXPORT_NOTES.txt" <<EOF
Portable Codex bundle created at:
$DEST
Included:
- config.toml
- AGENTS.md
- memories/
- rules/
- repo templates, memory, docs, and scripts
Excluded on purpose:
- auth.json
- sessions/
- logs SQLite files
- state SQLite files
- cache/
- plugins/
EOF
echo "Exported portable bundle to: $DEST"
+94
View File
@@ -0,0 +1,94 @@
#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
STAMP="$(date +%Y%m%d-%H%M%S)"
BACKUP_DIR="$CODEX_HOME/backups/$STAMP"
MANAGED_CONFIG="$REPO_ROOT/templates/global/config-managed.toml"
mkdir -p "$CODEX_HOME" "$BACKUP_DIR" "$CODEX_HOME/memories"
if [[ -f "$CODEX_HOME/config.toml" ]]; then
cp "$CODEX_HOME/config.toml" "$BACKUP_DIR/config.toml.bak"
fi
if [[ -f "$CODEX_HOME/AGENTS.md" ]]; then
cp "$CODEX_HOME/AGENTS.md" "$BACKUP_DIR/AGENTS.md.bak"
fi
cp "$REPO_ROOT/templates/global/AGENTS.md" "$CODEX_HOME/AGENTS.md"
python3 - "$CODEX_HOME/config.toml" "$MANAGED_CONFIG" <<'PY'
from pathlib import Path
import sys
config_path = Path(sys.argv[1])
managed_path = Path(sys.argv[2])
managed_start = "# >>> codex-ops-kit managed block >>>"
managed_end = "# <<< codex-ops-kit managed block <<<"
managed_root_keys = {
"model",
"model_reasoning_effort",
"profile",
"project_doc_max_bytes",
"web_search",
}
managed_sections = {
"history",
"profiles.economy",
"profiles.balanced",
"profiles.deep",
}
text = config_path.read_text() if config_path.exists() else ""
managed = managed_path.read_text().rstrip()
if managed_start in text and managed_end in text:
before = text.split(managed_start, 1)[0].rstrip()
else:
before = text.rstrip()
filtered_lines = []
current_section = None
for line in before.splitlines():
stripped = line.strip()
if stripped.startswith("[") and stripped.endswith("]"):
current_section = stripped[1:-1].strip()
if current_section in managed_sections:
continue
filtered_lines.append(line)
continue
if current_section in managed_sections:
continue
if "=" in line and not line.lstrip().startswith("#"):
key = line.split("=", 1)[0].strip()
if current_section is None and key in managed_root_keys:
continue
filtered_lines.append(line)
before = "\n".join(filtered_lines).strip()
block = f"{managed_start}\n{managed}\n{managed_end}\n"
if before:
config_path.write_text(before + "\n\n" + block)
else:
config_path.write_text(block)
PY
mkdir -p "$CODEX_HOME/memories/portable-kit"
cp "$REPO_ROOT"/memory/*.md "$CODEX_HOME/memories/portable-kit/"
echo "Installed Codex kit into: $CODEX_HOME"
echo "Backup created at: $BACKUP_DIR"
echo
echo "Next steps:"
echo "- Start Codex and use the balanced profile by default."
echo "- Switch to economy for lighter work and deep for hard tasks."
echo "- Run bash scripts/audit_codex_home.sh periodically."
+66
View File
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
set -euo pipefail
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
SESSIONS_DIR="$CODEX_HOME/sessions"
ARCHIVE_DIR="${CODEX_ARCHIVE_DIR:-$HOME/.codex_archives/sessions}"
OLDER_THAN_DAYS="${OLDER_THAN_DAYS:-30}"
MIN_SIZE_MB="${MIN_SIZE_MB:-50}"
APPLY=0
if [[ "${1:-}" == "--apply" ]]; then
APPLY=1
fi
if [[ ! -d "$SESSIONS_DIR" ]]; then
echo "Sessions directory not found: $SESSIONS_DIR" >&2
exit 1
fi
python3 - "$SESSIONS_DIR" "$ARCHIVE_DIR" "$OLDER_THAN_DAYS" "$MIN_SIZE_MB" "$APPLY" <<'PY'
from datetime import datetime, timedelta
from pathlib import Path
import shutil
import sys
sessions_dir = Path(sys.argv[1])
archive_dir = Path(sys.argv[2])
older_than_days = int(sys.argv[3])
min_size_mb = int(sys.argv[4])
apply = int(sys.argv[5])
cutoff = datetime.now() - timedelta(days=older_than_days)
candidates = []
for path in sessions_dir.rglob("*.jsonl"):
stat = path.stat()
mtime = datetime.fromtimestamp(stat.st_mtime)
size_mb = stat.st_size / (1024 * 1024)
if mtime < cutoff and size_mb >= min_size_mb:
candidates.append((size_mb, mtime, path))
candidates.sort(reverse=True)
if not candidates:
print("No session files matched the archive rules.")
raise SystemExit(0)
print("Candidates:")
for size_mb, mtime, path in candidates:
print(f"{size_mb:9.1f} MB {mtime:%Y-%m-%d} {path}")
if not apply:
print()
print("Dry run only. Re-run with --apply to move these files to:")
print(archive_dir)
raise SystemExit(0)
for _, _, path in candidates:
rel = path.relative_to(sessions_dir)
dest = archive_dir / rel
dest.parent.mkdir(parents=True, exist_ok=True)
shutil.move(str(path), str(dest))
print()
print(f"Archived {len(candidates)} session files to {archive_dir}")
PY
+109
View File
@@ -0,0 +1,109 @@
#!/usr/bin/env python3
from __future__ import annotations
import json
import re
import sys
from collections import OrderedDict
from pathlib import Path
def uniq(items: list[str]) -> list[str]:
return list(OrderedDict((item, None) for item in items if item))
def extract_texts(obj) -> list[str]:
texts: list[str] = []
if isinstance(obj, dict):
if obj.get("type") in {"input_text", "output_text"} and isinstance(obj.get("text"), str):
texts.append(obj["text"])
for value in obj.values():
texts.extend(extract_texts(value))
elif isinstance(obj, list):
for value in obj:
texts.extend(extract_texts(value))
return texts
def main() -> int:
if len(sys.argv) not in {2, 3}:
print("usage: session_to_memory.py SESSION_JSONL [OUTPUT_MD]", file=sys.stderr)
return 2
session_path = Path(sys.argv[1]).expanduser().resolve()
output_path = Path(sys.argv[2]).expanduser().resolve() if len(sys.argv) == 3 else session_path.with_suffix(".memory.md")
user_texts: list[str] = []
assistant_texts: list[str] = []
paths: list[str] = []
session_meta = {}
path_pattern = re.compile(r"(\/[A-Za-z0-9._ \-\/]+)")
with session_path.open() as handle:
for raw_line in handle:
raw_line = raw_line.strip()
if not raw_line:
continue
event = json.loads(raw_line)
payload = event.get("payload", {})
if event.get("type") == "session_meta":
session_meta = payload
if event.get("type") == "response_item" and payload.get("type") == "message":
role = payload.get("role")
texts = extract_texts(payload.get("content", []))
if role == "user":
user_texts.extend(texts)
elif role == "assistant":
assistant_texts.extend(texts)
for text in texts:
paths.extend(path_pattern.findall(text))
user_texts = uniq([text.strip() for text in user_texts if text.strip()])
assistant_texts = uniq([text.strip() for text in assistant_texts if text.strip()])
paths = uniq([path.strip() for path in paths if path.strip()])
output = []
output.append(f"# Session Memory Draft")
output.append("")
output.append(f"- Session file: `{session_path}`")
if session_meta.get("timestamp"):
output.append(f"- Session timestamp: `{session_meta['timestamp']}`")
if session_meta.get("cwd"):
output.append(f"- Working directory: `{session_meta['cwd']}`")
output.append("")
output.append("## User Requests")
output.append("")
for text in user_texts[:20]:
output.append(f"- {text.replace(chr(10), ' ')}")
output.append("")
output.append("## Candidate Paths Mentioned")
output.append("")
for path in paths[:30]:
output.append(f"- `{path}`")
output.append("")
output.append("## Assistant Notes To Distill")
output.append("")
output.append("- Copy only stable preferences, project facts, and durable decisions into your memory markdown files.")
output.append("- Do not copy transient debugging output or large transcript excerpts.")
output.append("- Summarize in your own words before adding to long-term memory.")
output.append("")
output.append("## Sample Durable Summary")
output.append("")
output.append("- Project:")
output.append("- User preference:")
output.append("- Important decision:")
output.append("- Follow-up worth remembering:")
output.append("")
output.append("## Assistant Messages Snapshot")
output.append("")
for text in assistant_texts[:10]:
output.append(f"- {text.replace(chr(10), ' ')}")
output_path.write_text("\n".join(output) + "\n")
print(output_path)
return 0
if __name__ == "__main__":
raise SystemExit(main())