aline-ai 0.6.2__py3-none-any.whl → 0.6.4__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.
Files changed (40) hide show
  1. {aline_ai-0.6.2.dist-info → aline_ai-0.6.4.dist-info}/METADATA +1 -1
  2. {aline_ai-0.6.2.dist-info → aline_ai-0.6.4.dist-info}/RECORD +38 -37
  3. realign/__init__.py +1 -1
  4. realign/adapters/__init__.py +0 -3
  5. realign/adapters/codex.py +14 -9
  6. realign/cli.py +42 -236
  7. realign/codex_detector.py +72 -32
  8. realign/codex_home.py +85 -0
  9. realign/codex_terminal_linker.py +172 -0
  10. realign/commands/__init__.py +2 -2
  11. realign/commands/add.py +89 -9
  12. realign/commands/doctor.py +495 -0
  13. realign/commands/export_shares.py +154 -226
  14. realign/commands/init.py +66 -4
  15. realign/commands/watcher.py +30 -80
  16. realign/config.py +9 -46
  17. realign/dashboard/app.py +7 -11
  18. realign/dashboard/screens/event_detail.py +0 -3
  19. realign/dashboard/screens/session_detail.py +0 -1
  20. realign/dashboard/tmux_manager.py +129 -4
  21. realign/dashboard/widgets/config_panel.py +175 -241
  22. realign/dashboard/widgets/events_table.py +71 -128
  23. realign/dashboard/widgets/sessions_table.py +77 -136
  24. realign/dashboard/widgets/terminal_panel.py +349 -27
  25. realign/dashboard/widgets/watcher_panel.py +0 -2
  26. realign/db/sqlite_db.py +77 -2
  27. realign/events/event_summarizer.py +76 -35
  28. realign/events/session_summarizer.py +73 -32
  29. realign/hooks.py +334 -647
  30. realign/llm_client.py +201 -520
  31. realign/triggers/__init__.py +0 -2
  32. realign/triggers/next_turn_trigger.py +4 -5
  33. realign/triggers/registry.py +1 -4
  34. realign/watcher_core.py +53 -35
  35. realign/adapters/antigravity.py +0 -159
  36. realign/triggers/antigravity_trigger.py +0 -140
  37. {aline_ai-0.6.2.dist-info → aline_ai-0.6.4.dist-info}/WHEEL +0 -0
  38. {aline_ai-0.6.2.dist-info → aline_ai-0.6.4.dist-info}/entry_points.txt +0 -0
  39. {aline_ai-0.6.2.dist-info → aline_ai-0.6.4.dist-info}/licenses/LICENSE +0 -0
  40. {aline_ai-0.6.2.dist-info → aline_ai-0.6.4.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aline-ai
3
- Version: 0.6.2
3
+ Version: 0.6.4
4
4
  Summary: Shared AI memory; everyone knows everything in teams
5
5
  Author: Sharemind
6
6
  License: MIT
@@ -1,27 +1,28 @@
1
- aline_ai-0.6.2.dist-info/licenses/LICENSE,sha256=H8wTqV5IF1oHw_HbBtS1PSDU8G_q81yblEIL_JfV8Vo,1077
2
- realign/__init__.py,sha256=WCultxtZIKlfMhrDP35gb3Jtyvc7vOLpx-I1JO6nPAc,1623
1
+ aline_ai-0.6.4.dist-info/licenses/LICENSE,sha256=H8wTqV5IF1oHw_HbBtS1PSDU8G_q81yblEIL_JfV8Vo,1077
2
+ realign/__init__.py,sha256=rnvZkVu_IlHB3KpP9LQEl-T4lLSwL0cvZOT9ycHF13o,1623
3
3
  realign/auth.py,sha256=d_1yvCwluN5iIrdgjtuSKpOYAksDzrzNgntKacLVJrw,16583
4
4
  realign/claude_detector.py,sha256=ZLSJacMo6zzQclXByABKA70UNpstxqIv3fPGqdpA934,2792
5
- realign/cli.py,sha256=M8lpAkDaE2ZjESzrlksFk8M8cpbFKkIzK3y8qNnZmJo,43793
6
- realign/codex_detector.py,sha256=N9ulgMgvTzDfXE4s4vLd6OoS0hT7R6h2bDFFXWa-2hE,4183
7
- realign/config.py,sha256=d8HQ6v1xju6cjNGbR7LlfHaMyvFPcMDofhGbepxpQq8,11634
5
+ realign/cli.py,sha256=HZ_1Rm50z1oszCwvPAZcAdPt0Gl-dj0S0NMLy2sWu_4,35665
6
+ realign/codex_detector.py,sha256=xTpYgMfUwL6UL76xeHl8xF2ZBPHdjwmgXmbmZkvHA0A,5523
7
+ realign/codex_home.py,sha256=gAAosBDru4jfz0QCn12A2bZEC_lZxytpOAzk7GOXTpI,2512
8
+ realign/codex_terminal_linker.py,sha256=9cDUHhN7MhCIUOfb-3kApPY-l6s91jq2qq_WI0ccexY,5926
9
+ realign/config.py,sha256=Znfs43AjiK90LGWnArDPWyrE859sdZQAPIb0KAcU3Ig,9252
8
10
  realign/context.py,sha256=8hzgNOg-7_eMW22wt7OM5H9IsmMveKXCv0epG7E0G7w,13917
9
11
  realign/file_lock.py,sha256=kLNm1Rra4TCrTMyPM5fwjVascq-CUz2Bzh9HHKtCKOE,3444
10
- realign/hooks.py,sha256=NR4LgWgkA6npW_B68I7OdCaZNWseYSP7ZbK4Sl5nnTo,74692
11
- realign/llm_client.py,sha256=KPfJScQvqse-Tm-VpqnZ6C5jvajPl2n4Ddz9sUp7WIY,24564
12
+ realign/hooks.py,sha256=wSSIjS5x9w7fm9LUcL63Lf7bglEfb75dHFja_znKDDQ,65134
13
+ realign/llm_client.py,sha256=QqMPDFE-aXm7oz0QAkB90CN0Qn0uz7JOxpWbUUlHNgU,11141
12
14
  realign/logging_config.py,sha256=LCAigKFhTj86PSJm4-kUl3Ag9h_GENh3x2iPnMv7qUI,4871
13
15
  realign/mcp_server.py,sha256=LWiQ2qukYoNLsoV2ID2f0vF9jkJlBvB587HpM5jymgE,10193
14
16
  realign/mcp_watcher.py,sha256=aK4jWStv7CoCroS4tXFHgZ_y_-q4QDjrpWgm4DxcEj4,1260
15
17
  realign/redactor.py,sha256=Zsoi5HfYak2yPmck20JArhm-1cPSB78IdkBJiNVXfrc,17096
16
- realign/watcher_core.py,sha256=k9esacTBfHpa77MPEXAsiMDiFa4Ml52vWfGGT-IucAM,108135
18
+ realign/watcher_core.py,sha256=0XCoA5giuie-Ytc_tlPTVbZH8EFRPmODu7DUYRhRBGo,108598
17
19
  realign/watcher_daemon.py,sha256=OHUQ9P1LlagKJHfrf6uRnzO-zDtBRXIxt8ydMFHf5S8,3475
18
20
  realign/worker_core.py,sha256=TXioUVJlOO-8EgmKssCTLIyuh0aaupRLb1sh9s3kSuc,10194
19
21
  realign/worker_daemon.py,sha256=X7Xyjw_u6m6KG4E84nx0HpDFw4cWMv8ja1G8btc9PiM,3957
20
- realign/adapters/__init__.py,sha256=bpDm5aBxMdq4OA_beYahoUb4zfNaq3KOG6KghQJruRc,827
21
- realign/adapters/antigravity.py,sha256=geaYxAEswpgsVtERqsQ1OwvPFsy5tRkyjx2yQ-Uq9nM,5461
22
+ realign/adapters/__init__.py,sha256=alkJr7DRn_CrJecSJRjRJOHHnkz9EnZ5TnsU8n1Bb0k,719
22
23
  realign/adapters/base.py,sha256=2IdAZKGjg5gPB3YLf_8r3V4XAdbK7fHpj06GjjsYEFY,7409
23
24
  realign/adapters/claude.py,sha256=ksTRwC5Z8AzUcB21LFjx6DETP08cv__fjgBzm-TeZdI,5444
24
- realign/adapters/codex.py,sha256=5ex3zJ5Hpb_StV2CcBSHVhHleygZxzVJjYsWw8qK1Bc,2051
25
+ realign/adapters/codex.py,sha256=VJgmrRzOO5a6GNG6xL7gJwzcvA2CBmHdilYkj0qffBw,2233
25
26
  realign/adapters/gemini.py,sha256=NvtXQPWUtEY-DaAAMvLGvQW4FalTG-g0pD514HYnzF0,2540
26
27
  realign/adapters/registry.py,sha256=yM6nf9nGTJ1vaK2Uixp-VacseK7PmxZkCdKedmWI8MA,3255
27
28
  realign/claude_hooks/__init__.py,sha256=MT9c8TWjLO23xDCM-uBBMy_mOThNd7O-AgN_Khn30qs,594
@@ -32,44 +33,45 @@ realign/claude_hooks/stop_hook_installer.py,sha256=uyqKOqpix7CQP64ERBvvh7viSPp_w
32
33
  realign/claude_hooks/terminal_state.py,sha256=i8B6b_2_9ttPEemp7SrGdFRJSa-vm5lc7YSTRTvAWNg,5397
33
34
  realign/claude_hooks/user_prompt_submit_hook.py,sha256=kMrmhAVtfV41oTX7JZcq2HPXjgQQ5gX26iOJoHJkfqA,10474
34
35
  realign/claude_hooks/user_prompt_submit_hook_installer.py,sha256=2xLF8yZcE7Iwib9gU-xCkA1NWxNH9Nc5CFKPYK7rtXw,5371
35
- realign/commands/__init__.py,sha256=sx_ck55oxaoiF4N3LugG0ZXwonUDxeEZ5uHbBKCC7K8,89
36
- realign/commands/add.py,sha256=njZgg3paUmOw-sb-sWkXr_eUaf5bD-hBEiRectaphPs,24332
36
+ realign/commands/__init__.py,sha256=WVaVT1orM2Z0PYaG3X6tkKb_t2v3n_3siCadh1qd_QA,107
37
+ realign/commands/add.py,sha256=_Xzt9P15mwndA3JvBBVrki8tn9Cc0UP6SiLwM4RS8Nc,27232
37
38
  realign/commands/auth.py,sha256=QrPukpP-ogYEDSwztV0NOYI-HDgn5fPxlCQ1-e2n7gU,11082
38
39
  realign/commands/config.py,sha256=nYnu_h2pk7GODcrzrV04K51D-s7v06FlRXHJ0HJ-gvU,6732
39
40
  realign/commands/context.py,sha256=pM2KfZHVkB-ou4nBhFvKSwnYliLBzwN3zerLyBAbhfE,7095
40
- realign/commands/export_shares.py,sha256=g2SxlPEb7FPMarjTZcoZntviZo5JdqEe-M28vggc2-s,136601
41
+ realign/commands/doctor.py,sha256=CpS8feMMuV2VvqzSCLal7yWDVSQHan5VbC2LbkLHB5Y,18173
42
+ realign/commands/export_shares.py,sha256=WNOR7FBE2om9qPO_28edZKhs94lyUAcbRgP_kNaDi5M,132574
41
43
  realign/commands/import_shares.py,sha256=HiswLlYHqR0dR3wgB7Rs54_WownqahIs5IdyJOHuot8,25572
42
- realign/commands/init.py,sha256=nhP1Qjl6Xo5R1ry_iTGVu3RwMxP-pYT5Z50NdzEMKrY,32756
44
+ realign/commands/init.py,sha256=6rBr1LVIrQLbUH_UvoDhkF1qXmMh2xkjNWCYAUz5Tho,35274
43
45
  realign/commands/restore.py,sha256=s2BxQZHxQw9r12NzRVsK20KlGafy5AIoSjWMo5PcnHY,11173
44
46
  realign/commands/search.py,sha256=QJrC0hln9sCDFxXbpo0nPGMHXrud18qA5QfRyD0z6fQ,25926
45
47
  realign/commands/upgrade.py,sha256=L3PLOUIN5qAQTbkfoVtSsIbbzEezA_xjjk9F1GMVfjw,12781
46
- realign/commands/watcher.py,sha256=rB3x2diC7scqghl7wLAeBNgMj4NLXUKbr0ou1_VVUIU,136292
48
+ realign/commands/watcher.py,sha256=4WTThIgr-Z5guKh_JqGDcPmerr97XiHrVaaijmckHsA,134350
47
49
  realign/commands/worker.py,sha256=jTu7Pj60nTnn7SsH3oNCNnO6zl4TIFCJVNSC1OoQ_0o,23363
48
50
  realign/dashboard/__init__.py,sha256=QZkHTsGityH8UkF8rmvA3xW7dMXNe0swEWr443qfgCM,128
49
- realign/dashboard/app.py,sha256=yy2rjMQuAfpukFgrA6udAnAbCXQoAHr9WeeuZ9bCSa4,16064
51
+ realign/dashboard/app.py,sha256=xCYICKoEsvPli8SCUgfPkInCQp6VDrymnVoRhOizYwY,15872
50
52
  realign/dashboard/layout.py,sha256=sZxmFj6QTbkois9MHTvBEMMcnaRVehCDqugdbiFx10k,9072
51
53
  realign/dashboard/terminal_backend.py,sha256=MlDfwtqhftyQK6jDNizQGFjAWIo5Bx2TDpSnP3MCZVM,3375
52
- realign/dashboard/tmux_manager.py,sha256=K8sjzSBtISLuWF7s4g4YieJ4oiE5wIgSztFvmhJZd0M,26849
54
+ realign/dashboard/tmux_manager.py,sha256=1DqMLdgE1m_MHABAilPpfizawk8D8c9QMVmnJ7Au4sg,30963
53
55
  realign/dashboard/backends/__init__.py,sha256=POROX7YKtukYZcLB1pi_kO0sSEpuO3y-hwmF3WIN1Kk,163
54
56
  realign/dashboard/backends/iterm2.py,sha256=XYYJT5lrrp4pW_MyEqPZYkRI0qyKUwJlezwMidgnsHc,21390
55
57
  realign/dashboard/backends/kitty.py,sha256=5jdkR1f2PwB8a4SnS3EG6uOQ2XU-PB7-cpKBfIJq3hU,12066
56
58
  realign/dashboard/screens/__init__.py,sha256=US6sAmQs5VVkH2tFkH_z0WDT4H8cVhLL-JckfSR1yQY,446
57
59
  realign/dashboard/screens/create_agent.py,sha256=06uiQYvz-Xvn4Xm689o3tdhzb2HQ0gdzAA1WHVEwziM,11706
58
60
  realign/dashboard/screens/create_event.py,sha256=oiQY1zKpUYnQU-5fQLeuZH9BV5NClE5B5XZIVBYG5A8,5506
59
- realign/dashboard/screens/event_detail.py,sha256=OLaL3-FgAohDdzVlfuUw5yh2SR49IHIpCtiqXJhBTc0,20992
61
+ realign/dashboard/screens/event_detail.py,sha256=Fcm1CPAJkrNzolnFyIAzLeE_-NAoqdjQ0dLW0YyyER8,20842
60
62
  realign/dashboard/screens/help_screen.py,sha256=Icrcvbgyz49R2tBiu8vBZ4CLm6iYclv_-FTa2pCFRRQ,3398
61
- realign/dashboard/screens/session_detail.py,sha256=gfpUIhMO00ecMlMyzpkxDdvGb9zhESEvxwrJvqLuHOI,9603
63
+ realign/dashboard/screens/session_detail.py,sha256=TBkHqSHyMxsLB2QdZq9m1EoiH8oRVDbPrjt-a8I9sHs,9561
62
64
  realign/dashboard/screens/share_import.py,sha256=hl2x0yGVycsoUI76AmdZTAV-br3Q6191g5xHHrZ8hOA,6318
63
65
  realign/dashboard/styles/dashboard.tcss,sha256=ewonevBGLN-dfSsgxUk4VBCPchtxY4rx_vj1u6Ox2Fw,3454
64
66
  realign/dashboard/widgets/__init__.py,sha256=3Pf2_K9obrertgv_psfxradgkI9RXlmjoXYQH7oBKm0,583
65
- realign/dashboard/widgets/config_panel.py,sha256=JRv9Hgm5V-vqVptS7gQqnjg5MbKpt_FmdZV13D4E9A4,17894
66
- realign/dashboard/widgets/events_table.py,sha256=Ru4y5Xq04Y-3CN9Dwm-fHrHR37Aup9NFW_Yh-J1x-Jo,33247
67
+ realign/dashboard/widgets/config_panel.py,sha256=v9wQIsH9CK7Q6HFz-C14IQ1SYBcJL3RjhV_ngTk0KH0,15723
68
+ realign/dashboard/widgets/events_table.py,sha256=MKB1G1_xdQCujEhmMz_GKI4hs-PeEiqGEAH7Y3ZGanE,30852
67
69
  realign/dashboard/widgets/header.py,sha256=0HHCFXX7F3C6HII-WDwOJwWkJrajmKPWmdoMWyOkn9E,1587
68
70
  realign/dashboard/widgets/openable_table.py,sha256=GeJPDEYp0kRHShqvmPMzAePpYXRZHUNqcWNnxqsqxjA,1963
69
71
  realign/dashboard/widgets/search_panel.py,sha256=ZNJDfwDSxUFnCeltYQYsQsPJ6t4HDeNWpENoTOoBdVM,8951
70
- realign/dashboard/widgets/sessions_table.py,sha256=GyaWzvt-elKx1iE2YR94CBNPyjqM8B7g0j7zsukiXi0,36517
71
- realign/dashboard/widgets/terminal_panel.py,sha256=BZgh7lo9rhuJdvSGBhUPlWjS3KjcXDJP7SSnNngmFaY,45805
72
- realign/dashboard/widgets/watcher_panel.py,sha256=O_mdDacgc87xA-5KEfta53Ik_Xsk_B2OfwenMOTtGw8,19722
72
+ realign/dashboard/widgets/sessions_table.py,sha256=oMkYhQ55pUGOGYxEXM5P37mpGYA350BK8Rb8fVq9AS4,34008
73
+ realign/dashboard/widgets/terminal_panel.py,sha256=VM0eyE8VDldhrc130JjSvCkkcpr5Io0Gx16i5cbdJgM,57854
74
+ realign/dashboard/widgets/watcher_panel.py,sha256=emVY1-aot9Dnf5UI9yyNeEmp4d2Gb-lrC28DjkeLjKA,19575
73
75
  realign/dashboard/widgets/worker_panel.py,sha256=F_jKWABuCNmjQgeeuCr4KnFRKdY4CLTNcEXMYwsNaSk,18691
74
76
  realign/db/__init__.py,sha256=65LsNdsq_rkwNC1eg1OAr3HC0ORXtelOh0I8MhNGr-g,3288
75
77
  realign/db/base.py,sha256=5baEwoGR5X2SyQXkXuyeUP2zelcuQardVouD2S-qils,13703
@@ -77,27 +79,26 @@ realign/db/locks.py,sha256=yzCiPJZ4eOQX-Q4mXB6s76U2U7lXAzIBBy1t59w-AVU,1698
77
79
  realign/db/migrate_agents.py,sha256=cDeVUzKW950dJ0lV74QObHuONqKwErSrXI5akU2vBmQ,9633
78
80
  realign/db/migration.py,sha256=af1QFEfIh_qX0pFyXzm5gWFVbQn0sKOUNLSJHlr__FU,13405
79
81
  realign/db/schema.py,sha256=YHj5PGZWbCl0VG0epnMF_Ofg3jRiLHq6SLHCi1q34eQ,30181
80
- realign/db/sqlite_db.py,sha256=AJb05gWN8L7K79-f9TJ0UGqGnoHUED1z-yjufGQTyQE,104929
82
+ realign/db/sqlite_db.py,sha256=nihEZ71wg1BXiVG1QU488ed9Q-ZasoVKYVS4j20hhtY,107223
81
83
  realign/events/__init__.py,sha256=IM-NxF4Zk2hYFD07k4WrfNRuuiC9ihGjf4GBpJhjd2E,35
82
84
  realign/events/debouncer.py,sha256=U3Q7dYpnMsAgWsW_E_IbSC4lrdEoi6H_SFLGLOAazs4,3062
83
- realign/events/event_summarizer.py,sha256=ZLiwOXWN8eawep3cQs3Wh9QLSypvU1SRbe8GTJXJQaY,8272
84
- realign/events/session_summarizer.py,sha256=W5J1zZs1ZrH0MvWgvPObwB1KFdxXEZMLctAmFQC_rok,10994
85
+ realign/events/event_summarizer.py,sha256=jJtWM8UWtsG4KGdzYicMqcTxrncWzGNEQs5vdBJPyew,10185
86
+ realign/events/session_summarizer.py,sha256=EzFFjgcUEAqm1IJuxOAPx74GTUIStyXTvQ9maZ-V10U,12888
85
87
  realign/models/event.py,sha256=ypz74D4l6U2U0RhgL8fzEhiq7iQjhHybmAdLUNDY7P4,5521
86
88
  realign/prompts/__init__.py,sha256=PpYR7f-T96fd-QyNYJDRS1U6h9O0rIt_SMsREy9i3aA,443
87
89
  realign/prompts/presets.py,sha256=h9oEy0XP4JQ4DCnp8HN_FfF0LmI-yOV6xWJLknIghJ8,7256
88
90
  realign/tracker/__init__.py,sha256=Apd-xxomkiOjSIthseqZpVQ8l0yT4nkaErsUyA1ptIE,161
89
- realign/triggers/__init__.py,sha256=esF-rMxaxzKDAEX4eLJRdUcVkpSU2_r6U37igS7jrIQ,674
90
- realign/triggers/antigravity_trigger.py,sha256=sj9OKu2TihNlgOAd2B9XLy5wfJpY5VfJSast7Krl4bg,5195
91
+ realign/triggers/__init__.py,sha256=EUMWFX6CNJbXw3rrB1C7jn3QF0QgzbsLIZLiMcMZOo4,596
91
92
  realign/triggers/base.py,sha256=Q72nlPMnCB3SP14gd4hm6AjS0mVyq5lbtlLUxSxAvrY,4148
92
93
  realign/triggers/claude_trigger.py,sha256=-LY2sR-FTEXlCBx8SOI6TxP5-RI2BtlfzqvLeT5U3mw,20065
93
94
  realign/triggers/codex_trigger.py,sha256=X8WNphoav86XNd05SJBoxpHySlFtEYCrjsEF-b6pw8M,13967
94
95
  realign/triggers/gemini_trigger.py,sha256=878GDjxuJ8WCXEBbCLSN2k2l_3BSGzvykhZi3gfIOqw,7939
95
- realign/triggers/next_turn_trigger.py,sha256=BpP0PWn4mU1MZd6mv89jWcjs8Jtv0zEWapW32O0wcHk,4333
96
- realign/triggers/registry.py,sha256=cb-AVLbYB2pqwfWL3q1DQxLv4kOw7g7m-GshTdfFESc,3827
96
+ realign/triggers/next_turn_trigger.py,sha256=-x80_I-WmIjXXzQHEPBykgx_GQW6oKaLDQx3dnPl53s,4194
97
+ realign/triggers/registry.py,sha256=dkIjSd8Bg-hF0nxaO2Fi2K-0Zipqv6vVjc-HYSrA_fY,3656
97
98
  realign/triggers/turn_status.py,sha256=wAZEhXDAmDoX5F-ohWfSnZZ0eA6DAJ9svSPiSv_f6sg,6041
98
99
  realign/triggers/turn_summary.py,sha256=f3hEUshgv9skJ9AbfWpoYs417lsv_HK2A_vpPjgryO4,4467
99
- aline_ai-0.6.2.dist-info/METADATA,sha256=KJbwjx2uZdXBhG2HyeVUs77RT72msrkJLRYBlCrldVc,1597
100
- aline_ai-0.6.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
101
- aline_ai-0.6.2.dist-info/entry_points.txt,sha256=TvYELpMoWsUTcQdMV8tBHxCbEf_LbK4sESqK3r8PM6Y,78
102
- aline_ai-0.6.2.dist-info/top_level.txt,sha256=yIL3s2xv9nf1GwD5n71Aq_JEIV4AfzCIDNKBzewuRm4,8
103
- aline_ai-0.6.2.dist-info/RECORD,,
100
+ aline_ai-0.6.4.dist-info/METADATA,sha256=NkBV9ESnpMtnqqp3cn6XcEYhJUjtSMndUS5QIpYP5oY,1597
101
+ aline_ai-0.6.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
102
+ aline_ai-0.6.4.dist-info/entry_points.txt,sha256=TvYELpMoWsUTcQdMV8tBHxCbEf_LbK4sESqK3r8PM6Y,78
103
+ aline_ai-0.6.4.dist-info/top_level.txt,sha256=yIL3s2xv9nf1GwD5n71Aq_JEIV4AfzCIDNKBzewuRm4,8
104
+ aline_ai-0.6.4.dist-info/RECORD,,
realign/__init__.py CHANGED
@@ -3,7 +3,7 @@
3
3
  import hashlib
4
4
  from pathlib import Path
5
5
 
6
- __version__ = "0.6.2"
6
+ __version__ = "0.6.4"
7
7
 
8
8
 
9
9
  def get_realign_dir(project_root: Path) -> Path:
@@ -11,14 +11,12 @@ from .registry import AdapterRegistry, get_adapter_registry
11
11
  from .claude import ClaudeAdapter
12
12
  from .codex import CodexAdapter
13
13
  from .gemini import GeminiAdapter
14
- from .antigravity import AntigravityAdapter
15
14
 
16
15
  # Register all built-in adapters
17
16
  registry = get_adapter_registry()
18
17
  registry.register(ClaudeAdapter)
19
18
  registry.register(CodexAdapter)
20
19
  registry.register(GeminiAdapter)
21
- registry.register(AntigravityAdapter)
22
20
 
23
21
  __all__ = [
24
22
  "SessionAdapter",
@@ -27,5 +25,4 @@ __all__ = [
27
25
  "ClaudeAdapter",
28
26
  "CodexAdapter",
29
27
  "GeminiAdapter",
30
- "AntigravityAdapter",
31
28
  ]
realign/adapters/codex.py CHANGED
@@ -21,17 +21,22 @@ class CodexAdapter(SessionAdapter):
21
21
 
22
22
  def discover_sessions(self) -> List[Path]:
23
23
  """Find all Codex sessions."""
24
- sessions = []
25
- codex_sessions_base = Path.home() / ".codex" / "sessions"
26
-
27
- if not codex_sessions_base.exists():
28
- return sessions
29
-
30
- # Find all session files recursively
24
+ sessions: list[Path] = []
25
+ roots: list[Path] = []
31
26
  try:
32
- sessions.extend(codex_sessions_base.rglob("rollout-*.jsonl"))
27
+ from ..codex_detector import _codex_session_roots # type: ignore[attr-defined]
28
+
29
+ roots = _codex_session_roots()
33
30
  except Exception:
34
- pass
31
+ roots = [Path.home() / ".codex" / "sessions"]
32
+
33
+ for root in roots:
34
+ if not root.exists():
35
+ continue
36
+ try:
37
+ sessions.extend(root.rglob("rollout-*.jsonl"))
38
+ except Exception:
39
+ continue
35
40
 
36
41
  return sessions
37
42
 
realign/cli.py CHANGED
@@ -7,7 +7,19 @@ from typing import Optional
7
7
  from rich.console import Console
8
8
  from rich.syntax import Syntax
9
9
 
10
- from .commands import init, config, watcher, worker, export_shares, search, upgrade, restore, add, auth
10
+ from .commands import (
11
+ init,
12
+ config,
13
+ watcher,
14
+ worker,
15
+ export_shares,
16
+ search,
17
+ upgrade,
18
+ restore,
19
+ add,
20
+ auth,
21
+ doctor,
22
+ )
11
23
 
12
24
  app = typer.Typer(
13
25
  name="realign",
@@ -33,6 +45,22 @@ def main(
33
45
  ctx.obj["dev"] = dev
34
46
 
35
47
  if ctx.invoked_subcommand is None:
48
+ def _needs_global_init() -> bool:
49
+ config_path = Path.home() / ".aline" / "config.yaml"
50
+ if not config_path.exists():
51
+ return True
52
+ try:
53
+ from .config import ReAlignConfig
54
+
55
+ cfg = ReAlignConfig.load(config_path)
56
+ db_path = Path(cfg.sqlite_db_path).expanduser()
57
+ if not db_path.exists():
58
+ return True
59
+ except Exception:
60
+ return True
61
+ prompts_dir = Path.home() / ".aline" / "prompts"
62
+ return not prompts_dir.exists()
63
+
36
64
  # Check login status before launching dashboard
37
65
  from .auth import is_logged_in, get_current_user
38
66
 
@@ -53,6 +81,17 @@ def main(
53
81
 
54
82
  console.print() # Add spacing before dashboard launch
55
83
 
84
+ # First run after install/upgrade: ensure global artifacts exist.
85
+ if _needs_global_init():
86
+ console.print("[dim]First run detected. Running 'aline init'...[/dim]\n")
87
+ try:
88
+ from .commands import init as init_cmd
89
+
90
+ init_cmd.init_command(force=False, start_watcher=None)
91
+ except typer.Exit as e:
92
+ if getattr(e, "exit_code", 1) != 0:
93
+ raise
94
+
56
95
  # Check for updates before launching dashboard
57
96
  from .commands.upgrade import check_and_prompt_update
58
97
 
@@ -95,6 +134,7 @@ def main(
95
134
  app.command(name="init")(init.init_command)
96
135
  app.command(name="config")(config.config_command)
97
136
  app.command(name="upgrade")(upgrade.upgrade_command)
137
+ app.command(name="doctor")(doctor.doctor_command)
98
138
 
99
139
 
100
140
  # Auth commands
@@ -119,239 +159,6 @@ def whoami_cli():
119
159
  raise typer.Exit(code=exit_code)
120
160
 
121
161
 
122
- @app.command(name="doctor")
123
- def doctor_cli(
124
- no_restart: bool = typer.Option(False, "--no-restart", help="Only clear cache, don't restart daemons"),
125
- verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed output"),
126
- ):
127
- """
128
- Fix common issues after code updates.
129
-
130
- This command:
131
- - Clears Python bytecode cache (.pyc files)
132
- - Updates Claude Code hooks (Stop, UserPromptSubmit, PermissionRequest)
133
- - Updates skills to latest version
134
- - Ensures watcher daemon is running (restarts if running, starts if not)
135
- - Ensures worker daemon is running (restarts if running, starts if not)
136
-
137
- Run this after pulling new code to ensure everything uses the latest version.
138
- """
139
- import shutil
140
- import subprocess
141
- import signal
142
- import time
143
-
144
- # Find the project root (where src/realign is)
145
- project_root = Path(__file__).parent.parent.parent
146
-
147
- # 1. Clear Python cache
148
- console.print("[bold]1. Clearing Python cache...[/bold]")
149
- pyc_count = 0
150
- pycache_count = 0
151
-
152
- for pyc_file in project_root.rglob("*.pyc"):
153
- try:
154
- pyc_file.unlink()
155
- pyc_count += 1
156
- if verbose:
157
- console.print(f" [dim]Removed: {pyc_file}[/dim]")
158
- except Exception as e:
159
- if verbose:
160
- console.print(f" [yellow]Failed to remove {pyc_file}: {e}[/yellow]")
161
-
162
- for pycache_dir in project_root.rglob("__pycache__"):
163
- if pycache_dir.is_dir():
164
- try:
165
- shutil.rmtree(pycache_dir)
166
- pycache_count += 1
167
- if verbose:
168
- console.print(f" [dim]Removed: {pycache_dir}[/dim]")
169
- except Exception as e:
170
- if verbose:
171
- console.print(f" [yellow]Failed to remove {pycache_dir}: {e}[/yellow]")
172
-
173
- console.print(f" [green]✓[/green] Cleared {pyc_count} .pyc files, {pycache_count} __pycache__ directories")
174
-
175
- # 2. Update Claude Code hooks
176
- console.print("\n[bold]2. Updating Claude Code hooks...[/bold]")
177
- hooks_updated = []
178
- hooks_failed = []
179
-
180
- # Stop hook
181
- try:
182
- from .claude_hooks.stop_hook_installer import install_stop_hook, get_settings_path
183
- if install_stop_hook(get_settings_path(), quiet=True, force=True):
184
- hooks_updated.append("Stop")
185
- if verbose:
186
- console.print(" [dim]Stop hook updated[/dim]")
187
- else:
188
- hooks_failed.append("Stop")
189
- except Exception as e:
190
- hooks_failed.append("Stop")
191
- if verbose:
192
- console.print(f" [yellow]Stop hook failed: {e}[/yellow]")
193
-
194
- # UserPromptSubmit hook
195
- try:
196
- from .claude_hooks.user_prompt_submit_hook_installer import install_user_prompt_submit_hook, get_settings_path as get_submit_settings_path
197
- if install_user_prompt_submit_hook(get_submit_settings_path(), quiet=True, force=True):
198
- hooks_updated.append("UserPromptSubmit")
199
- if verbose:
200
- console.print(" [dim]UserPromptSubmit hook updated[/dim]")
201
- else:
202
- hooks_failed.append("UserPromptSubmit")
203
- except Exception as e:
204
- hooks_failed.append("UserPromptSubmit")
205
- if verbose:
206
- console.print(f" [yellow]UserPromptSubmit hook failed: {e}[/yellow]")
207
-
208
- # PermissionRequest hook
209
- try:
210
- from .claude_hooks.permission_request_hook_installer import install_permission_request_hook, get_settings_path as get_permission_settings_path
211
- if install_permission_request_hook(get_permission_settings_path(), quiet=True, force=True):
212
- hooks_updated.append("PermissionRequest")
213
- if verbose:
214
- console.print(" [dim]PermissionRequest hook updated[/dim]")
215
- else:
216
- hooks_failed.append("PermissionRequest")
217
- except Exception as e:
218
- hooks_failed.append("PermissionRequest")
219
- if verbose:
220
- console.print(f" [yellow]PermissionRequest hook failed: {e}[/yellow]")
221
-
222
- if hooks_updated:
223
- console.print(f" [green]✓[/green] Updated hooks: {', '.join(hooks_updated)}")
224
- if hooks_failed:
225
- console.print(f" [yellow]![/yellow] Failed hooks: {', '.join(hooks_failed)}")
226
-
227
- # 3. Update skills
228
- console.print("\n[bold]3. Updating skills...[/bold]")
229
- try:
230
- from .commands.add import add_skills_command
231
- # Capture output by redirecting - use force=True to update
232
- import io
233
- import contextlib
234
-
235
- stdout_capture = io.StringIO()
236
- with contextlib.redirect_stdout(stdout_capture):
237
- add_skills_command(force=True)
238
-
239
- output = stdout_capture.getvalue()
240
- # Count updated skills from output
241
- updated_count = output.count("✓")
242
- if updated_count > 0:
243
- console.print(f" [green]✓[/green] Updated {updated_count} skill(s)")
244
- else:
245
- console.print(" [green]✓[/green] Skills are up to date")
246
- if verbose and output.strip():
247
- for line in output.strip().split("\n"):
248
- console.print(f" [dim]{line}[/dim]")
249
- except Exception as e:
250
- console.print(f" [yellow]![/yellow] Failed to update skills: {e}")
251
-
252
- if no_restart:
253
- console.print("\n[dim]Skipping daemon restart (--no-restart)[/dim]")
254
- console.print("\n[green]Done![/green] Aline is ready with the latest code.")
255
- raise typer.Exit(code=0)
256
-
257
- # 4. Restart watcher daemon
258
- console.print("\n[bold]4. Checking watcher daemon...[/bold]")
259
- pid_file = Path.home() / ".aline" / ".logs" / "watcher.pid"
260
- watcher_was_running = False
261
-
262
- if pid_file.exists():
263
- try:
264
- pid = int(pid_file.read_text().strip())
265
- # Check if process is running
266
- try:
267
- import os
268
- os.kill(pid, 0) # Signal 0 just checks if process exists
269
- watcher_was_running = True
270
- console.print(f" [dim]Found watcher daemon (PID {pid}), stopping...[/dim]")
271
- os.kill(pid, signal.SIGTERM)
272
- time.sleep(1)
273
- # Force kill if still running
274
- try:
275
- os.kill(pid, 0)
276
- os.kill(pid, signal.SIGKILL)
277
- time.sleep(0.5)
278
- except ProcessLookupError:
279
- pass
280
- except ProcessLookupError:
281
- console.print(" [dim]Watcher daemon not running (stale PID file)[/dim]")
282
- except Exception as e:
283
- if verbose:
284
- console.print(f" [yellow]Error checking watcher: {e}[/yellow]")
285
-
286
- if watcher_was_running:
287
- console.print(" [dim]Starting watcher daemon...[/dim]")
288
- else:
289
- console.print(" [dim]Watcher daemon was not running, starting...[/dim]")
290
- try:
291
- subprocess.Popen(
292
- ["python", "-m", "src.realign.watcher_daemon"],
293
- stdout=subprocess.DEVNULL,
294
- stderr=subprocess.DEVNULL,
295
- start_new_session=True,
296
- cwd=str(project_root),
297
- )
298
- time.sleep(2)
299
- action = "restarted" if watcher_was_running else "started"
300
- console.print(f" [green]✓[/green] Watcher daemon {action}")
301
- except Exception as e:
302
- action = "restart" if watcher_was_running else "start"
303
- console.print(f" [red]✗[/red] Failed to {action} watcher: {e}")
304
-
305
- # 5. Restart worker daemon
306
- console.print("\n[bold]5. Checking worker daemon...[/bold]")
307
- worker_pid_file = Path.home() / ".aline" / ".logs" / "worker.pid"
308
- worker_was_running = False
309
-
310
- if worker_pid_file.exists():
311
- try:
312
- pid = int(worker_pid_file.read_text().strip())
313
- try:
314
- import os
315
- os.kill(pid, 0)
316
- worker_was_running = True
317
- console.print(f" [dim]Found worker daemon (PID {pid}), stopping...[/dim]")
318
- os.kill(pid, signal.SIGTERM)
319
- time.sleep(1)
320
- try:
321
- os.kill(pid, 0)
322
- os.kill(pid, signal.SIGKILL)
323
- time.sleep(0.5)
324
- except ProcessLookupError:
325
- pass
326
- except ProcessLookupError:
327
- console.print(" [dim]Worker daemon not running (stale PID file)[/dim]")
328
- except Exception as e:
329
- if verbose:
330
- console.print(f" [yellow]Error checking worker: {e}[/yellow]")
331
-
332
- if worker_was_running:
333
- console.print(" [dim]Starting worker daemon...[/dim]")
334
- else:
335
- console.print(" [dim]Worker daemon was not running, starting...[/dim]")
336
- try:
337
- subprocess.Popen(
338
- ["python", "-m", "src.realign.worker_daemon"],
339
- stdout=subprocess.DEVNULL,
340
- stderr=subprocess.DEVNULL,
341
- start_new_session=True,
342
- cwd=str(project_root),
343
- )
344
- time.sleep(2)
345
- action = "restarted" if worker_was_running else "started"
346
- console.print(f" [green]✓[/green] Worker daemon {action}")
347
- except Exception as e:
348
- action = "restart" if worker_was_running else "start"
349
- console.print(f" [red]✗[/red] Failed to {action} worker: {e}")
350
-
351
- console.print("\n[green]Done![/green] Aline is ready with the latest code.")
352
- raise typer.Exit(code=0)
353
-
354
-
355
162
  @app.command(name="search")
356
163
  def search_cli(
357
164
  query: str = typer.Argument(..., help="Search query (keywords or regex pattern)"),
@@ -445,7 +252,7 @@ app.add_typer(add_app, name="add")
445
252
  @add_app.command(name="tmux")
446
253
  def add_tmux_cli():
447
254
  """Install tmux via Homebrew and set up Aline tmux clipboard bindings."""
448
- exit_code = add.add_tmux_command()
255
+ exit_code = add.add_tmux_command(install_brew=True)
449
256
  raise typer.Exit(code=exit_code)
450
257
 
451
258
 
@@ -828,7 +635,6 @@ def watcher_event_revise_slack_cli(
828
635
  exit_code = watcher.watcher_event_revise_slack_command(
829
636
  input_json=input_json,
830
637
  instruction=instruction,
831
- provider=provider,
832
638
  json_output=json_output,
833
639
  )
834
640
  raise typer.Exit(code=exit_code)