aline-ai 0.5.3__py3-none-any.whl → 0.5.5__py3-none-any.whl
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.
- {aline_ai-0.5.3.dist-info → aline_ai-0.5.5.dist-info}/METADATA +1 -1
- aline_ai-0.5.5.dist-info/RECORD +93 -0
- realign/__init__.py +1 -1
- realign/adapters/antigravity.py +28 -20
- realign/adapters/base.py +46 -50
- realign/adapters/claude.py +14 -14
- realign/adapters/codex.py +7 -7
- realign/adapters/gemini.py +11 -11
- realign/adapters/registry.py +14 -10
- realign/claude_detector.py +2 -2
- realign/claude_hooks/__init__.py +3 -3
- realign/claude_hooks/permission_request_hook.py +35 -0
- realign/claude_hooks/permission_request_hook_installer.py +31 -32
- realign/claude_hooks/stop_hook.py +4 -1
- realign/claude_hooks/stop_hook_installer.py +30 -31
- realign/cli.py +24 -0
- realign/codex_detector.py +11 -11
- realign/commands/add.py +361 -35
- realign/commands/config.py +3 -12
- realign/commands/context.py +3 -1
- realign/commands/export_shares.py +86 -127
- realign/commands/import_shares.py +145 -155
- realign/commands/init.py +166 -30
- realign/commands/restore.py +18 -6
- realign/commands/search.py +14 -42
- realign/commands/upgrade.py +155 -11
- realign/commands/watcher.py +98 -219
- realign/commands/worker.py +29 -6
- realign/config.py +25 -20
- realign/context.py +1 -3
- realign/dashboard/app.py +4 -4
- realign/dashboard/screens/create_event.py +3 -1
- realign/dashboard/screens/event_detail.py +14 -6
- realign/dashboard/screens/session_detail.py +3 -1
- realign/dashboard/screens/share_import.py +7 -3
- realign/dashboard/tmux_manager.py +91 -22
- realign/dashboard/widgets/config_panel.py +85 -1
- realign/dashboard/widgets/events_table.py +3 -1
- realign/dashboard/widgets/header.py +1 -0
- realign/dashboard/widgets/search_panel.py +37 -27
- realign/dashboard/widgets/sessions_table.py +24 -15
- realign/dashboard/widgets/terminal_panel.py +207 -17
- realign/dashboard/widgets/watcher_panel.py +6 -2
- realign/dashboard/widgets/worker_panel.py +10 -1
- realign/db/__init__.py +1 -1
- realign/db/base.py +5 -15
- realign/db/locks.py +0 -1
- realign/db/migration.py +82 -76
- realign/db/schema.py +2 -6
- realign/db/sqlite_db.py +23 -41
- realign/events/__init__.py +0 -1
- realign/events/event_summarizer.py +27 -15
- realign/events/session_summarizer.py +29 -15
- realign/file_lock.py +1 -0
- realign/hooks.py +150 -60
- realign/logging_config.py +12 -15
- realign/mcp_server.py +30 -51
- realign/mcp_watcher.py +0 -1
- realign/models/event.py +29 -20
- realign/prompts/__init__.py +7 -7
- realign/prompts/presets.py +15 -11
- realign/redactor.py +99 -59
- realign/triggers/__init__.py +9 -9
- realign/triggers/antigravity_trigger.py +30 -28
- realign/triggers/base.py +4 -3
- realign/triggers/claude_trigger.py +104 -85
- realign/triggers/codex_trigger.py +15 -5
- realign/triggers/gemini_trigger.py +57 -47
- realign/triggers/next_turn_trigger.py +3 -1
- realign/triggers/registry.py +6 -2
- realign/triggers/turn_status.py +3 -1
- realign/watcher_core.py +306 -131
- realign/watcher_daemon.py +8 -8
- realign/worker_core.py +3 -1
- realign/worker_daemon.py +3 -1
- aline_ai-0.5.3.dist-info/RECORD +0 -93
- {aline_ai-0.5.3.dist-info → aline_ai-0.5.5.dist-info}/WHEEL +0 -0
- {aline_ai-0.5.3.dist-info → aline_ai-0.5.5.dist-info}/entry_points.txt +0 -0
- {aline_ai-0.5.3.dist-info → aline_ai-0.5.5.dist-info}/licenses/LICENSE +0 -0
- {aline_ai-0.5.3.dist-info → aline_ai-0.5.5.dist-info}/top_level.txt +0 -0
|
@@ -31,6 +31,7 @@ def schedule_event_summary_update(db: SQLiteDatabase, event_id: str) -> None:
|
|
|
31
31
|
db: Database instance
|
|
32
32
|
event_id: ID of the event to update
|
|
33
33
|
"""
|
|
34
|
+
|
|
34
35
|
def do_update():
|
|
35
36
|
_update_event_summary(db, event_id)
|
|
36
37
|
|
|
@@ -122,10 +123,17 @@ def _get_event_summary_prompt() -> str:
|
|
|
122
123
|
logger.debug(f"Loaded user-customized event summary prompt from {user_prompt_path}")
|
|
123
124
|
return text
|
|
124
125
|
except Exception:
|
|
125
|
-
logger.debug(
|
|
126
|
+
logger.debug(
|
|
127
|
+
"Failed to load user-customized event summary prompt, falling back", exc_info=True
|
|
128
|
+
)
|
|
126
129
|
|
|
127
130
|
# Fall back to built-in prompt (tools/commit_message_prompts/event_summary.md)
|
|
128
|
-
candidate =
|
|
131
|
+
candidate = (
|
|
132
|
+
Path(__file__).resolve().parents[2]
|
|
133
|
+
/ "tools"
|
|
134
|
+
/ "commit_message_prompts"
|
|
135
|
+
/ "event_summary.md"
|
|
136
|
+
)
|
|
129
137
|
try:
|
|
130
138
|
if candidate.exists():
|
|
131
139
|
text = candidate.read_text(encoding="utf-8").strip()
|
|
@@ -184,19 +192,25 @@ def _generate_event_summary_llm(sessions: List[SessionRecord]) -> Tuple[str, str
|
|
|
184
192
|
# Build sessions payload for prompt
|
|
185
193
|
sessions_data = []
|
|
186
194
|
for i, session in enumerate(sessions):
|
|
187
|
-
sessions_data.append(
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
195
|
+
sessions_data.append(
|
|
196
|
+
{
|
|
197
|
+
"session_number": i + 1,
|
|
198
|
+
"title": session.session_title or f"Session {session.id[:8]}",
|
|
199
|
+
"summary": session.session_summary or "(no summary)",
|
|
200
|
+
"session_type": session.session_type,
|
|
201
|
+
}
|
|
202
|
+
)
|
|
193
203
|
|
|
194
204
|
system_prompt = _get_event_summary_prompt()
|
|
195
205
|
|
|
196
|
-
user_prompt = json.dumps(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
206
|
+
user_prompt = json.dumps(
|
|
207
|
+
{
|
|
208
|
+
"total_sessions": len(sessions),
|
|
209
|
+
"sessions": sessions_data,
|
|
210
|
+
},
|
|
211
|
+
ensure_ascii=False,
|
|
212
|
+
indent=2,
|
|
213
|
+
)
|
|
200
214
|
|
|
201
215
|
try:
|
|
202
216
|
# Use unified LLM client
|
|
@@ -205,7 +219,7 @@ def _generate_event_summary_llm(sessions: List[SessionRecord]) -> Tuple[str, str
|
|
|
205
219
|
user_prompt=user_prompt,
|
|
206
220
|
provider="auto", # Try Claude first, fallback to OpenAI
|
|
207
221
|
max_tokens=500,
|
|
208
|
-
purpose="event_summary"
|
|
222
|
+
purpose="event_summary",
|
|
209
223
|
)
|
|
210
224
|
|
|
211
225
|
if not response:
|
|
@@ -241,5 +255,3 @@ def _fallback_event_summary(sessions: List[SessionRecord]) -> Tuple[str, str]:
|
|
|
241
255
|
description = f"Event containing {len(sessions)} sessions."
|
|
242
256
|
|
|
243
257
|
return title[:100], description
|
|
244
|
-
|
|
245
|
-
|
|
@@ -176,13 +176,22 @@ def _get_session_summary_prompt() -> str:
|
|
|
176
176
|
text = user_prompt_path.read_text(encoding="utf-8").strip()
|
|
177
177
|
if text:
|
|
178
178
|
_SESSION_SUMMARY_PROMPT_CACHE = text
|
|
179
|
-
logger.debug(
|
|
179
|
+
logger.debug(
|
|
180
|
+
f"Loaded user-customized session summary prompt from {user_prompt_path}"
|
|
181
|
+
)
|
|
180
182
|
return text
|
|
181
183
|
except Exception:
|
|
182
|
-
logger.debug(
|
|
184
|
+
logger.debug(
|
|
185
|
+
"Failed to load user-customized session summary prompt, falling back", exc_info=True
|
|
186
|
+
)
|
|
183
187
|
|
|
184
188
|
# Fall back to built-in prompt (tools/commit_message_prompts/session_summary.md)
|
|
185
|
-
candidate =
|
|
189
|
+
candidate = (
|
|
190
|
+
Path(__file__).resolve().parents[2]
|
|
191
|
+
/ "tools"
|
|
192
|
+
/ "commit_message_prompts"
|
|
193
|
+
/ "session_summary.md"
|
|
194
|
+
)
|
|
186
195
|
try:
|
|
187
196
|
if candidate.exists():
|
|
188
197
|
text = candidate.read_text(encoding="utf-8").strip()
|
|
@@ -234,19 +243,25 @@ def _generate_session_summary_llm(turns: List[TurnRecord]) -> Tuple[str, str]:
|
|
|
234
243
|
# Build turns payload for prompt
|
|
235
244
|
turns_data = []
|
|
236
245
|
for i, turn in enumerate(turns):
|
|
237
|
-
turns_data.append(
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
246
|
+
turns_data.append(
|
|
247
|
+
{
|
|
248
|
+
"turn_number": i + 1,
|
|
249
|
+
"title": turn.llm_title or "(no title)",
|
|
250
|
+
"summary": turn.assistant_summary or "(no summary)",
|
|
251
|
+
"user_request": (turn.user_message or "")[:200], # Truncate long messages
|
|
252
|
+
}
|
|
253
|
+
)
|
|
243
254
|
|
|
244
255
|
system_prompt = _get_session_summary_prompt()
|
|
245
256
|
|
|
246
|
-
user_prompt = json.dumps(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
257
|
+
user_prompt = json.dumps(
|
|
258
|
+
{
|
|
259
|
+
"total_turns": len(turns),
|
|
260
|
+
"turns": turns_data,
|
|
261
|
+
},
|
|
262
|
+
ensure_ascii=False,
|
|
263
|
+
indent=2,
|
|
264
|
+
)
|
|
250
265
|
|
|
251
266
|
try:
|
|
252
267
|
# Use unified LLM client
|
|
@@ -255,7 +270,7 @@ def _generate_session_summary_llm(turns: List[TurnRecord]) -> Tuple[str, str]:
|
|
|
255
270
|
user_prompt=user_prompt,
|
|
256
271
|
provider="auto", # Try Claude first, fallback to OpenAI
|
|
257
272
|
max_tokens=500,
|
|
258
|
-
purpose="session_summary"
|
|
273
|
+
purpose="session_summary",
|
|
259
274
|
)
|
|
260
275
|
|
|
261
276
|
if not response:
|
|
@@ -290,4 +305,3 @@ def _fallback_summary(turns: List[TurnRecord]) -> Tuple[str, str]:
|
|
|
290
305
|
summary = "\n".join(f"- {s}" for s in recent) if recent else ""
|
|
291
306
|
|
|
292
307
|
return title, summary
|
|
293
|
-
|
realign/file_lock.py
CHANGED
|
@@ -109,6 +109,7 @@ def commit_lock(repo_path: Path, timeout: float = 10.0):
|
|
|
109
109
|
True if lock was acquired
|
|
110
110
|
"""
|
|
111
111
|
from realign import get_realign_dir
|
|
112
|
+
|
|
112
113
|
realign_dir = get_realign_dir(repo_path)
|
|
113
114
|
lock_file = realign_dir / ".commit.lock"
|
|
114
115
|
lock = FileLock(lock_file, timeout=timeout)
|