Initial release: aircontext
This commit is contained in:
73
scripts/cmd_now.py
Normal file
73
scripts/cmd_now.py
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Backend for /aircontext-now — force a compaction synchronously."""
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
_HERE = Path(__file__).resolve().parent
|
||||
sys.path.insert(0, str(_HERE))
|
||||
|
||||
from core.compactor import run as run_compactor # noqa: E402
|
||||
from core.state import StateFile # noqa: E402
|
||||
|
||||
|
||||
def _find_transcript(project: Path, session_id: str) -> Path | None:
|
||||
"""Locate the JSONL transcript for the given session.
|
||||
|
||||
Claude Code stores transcripts under
|
||||
~/.claude/projects/<encoded-cwd>/sessions/<session-id>.jsonl
|
||||
The cwd encoding replaces path separators with `-`. We search defensively.
|
||||
"""
|
||||
home = Path.home() / ".claude" / "projects"
|
||||
if not home.exists():
|
||||
return None
|
||||
encoded = str(project).replace(os.sep, "-").replace(":", "")
|
||||
# Try direct match first
|
||||
candidate = home / encoded / "sessions" / f"{session_id}.jsonl"
|
||||
if candidate.exists():
|
||||
return candidate
|
||||
# Fall back: scan for the session id under any project directory
|
||||
for p in home.glob(f"*/sessions/{session_id}.jsonl"):
|
||||
return p
|
||||
return None
|
||||
|
||||
|
||||
def main() -> int:
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument("--session-id", required=True)
|
||||
args = p.parse_args()
|
||||
|
||||
project = Path(os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd()))
|
||||
air = project / "AirContext"
|
||||
if not (air / "config.yaml").exists():
|
||||
print("AirContext not initialised. Run /aircontext-init first.")
|
||||
return 1
|
||||
|
||||
transcript = _find_transcript(project, args.session_id)
|
||||
if not transcript:
|
||||
print(f"Could not locate transcript for session {args.session_id}.")
|
||||
return 1
|
||||
|
||||
state = StateFile(air / "state.json")
|
||||
# Force one-shot regardless of cooldown
|
||||
state.update(last_compaction_unix=0)
|
||||
print(f"Compacting transcript: {transcript}")
|
||||
rc = run_compactor(project, transcript, args.session_id)
|
||||
snap = state.read()
|
||||
if rc == 0 and snap.get("compaction_ready"):
|
||||
print("Compaction prepared. The wrapper will restart claude shortly.")
|
||||
print("If you launched claude directly (without `aircontext`), exit and "
|
||||
f"run: claude --resume {args.session_id}")
|
||||
elif rc == 0:
|
||||
print("Compactor returned success but no compaction was applied "
|
||||
"(see compactor.log for reason — likely chain too short or paused).")
|
||||
else:
|
||||
print(f"Compactor failed with exit code {rc}. See AirContext/snapshots/compactor.log")
|
||||
return rc
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user