urkit 0.3.0__tar.gz → 0.3.3__tar.gz
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.
- {urkit-0.3.0 → urkit-0.3.3}/PKG-INFO +94 -2
- {urkit-0.3.0 → urkit-0.3.3}/README.md +93 -1
- {urkit-0.3.0 → urkit-0.3.3}/pyproject.toml +5 -1
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/__init__.py +1 -1
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/cli/points.py +1 -22
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/cli/teach.py +260 -50
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/config.py +1 -1
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/geometry.py +5 -5
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/gripper/base.py +12 -23
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/gripper/digital.py +1 -1
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/gripper/robotiq.py +9 -3
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/motion.py +12 -5
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/points.py +3 -2
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/robot.py +78 -25
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit.egg-info/PKG-INFO +94 -2
- {urkit-0.3.0 → urkit-0.3.3}/setup.cfg +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/__main__.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/cli/__init__.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/cli/colors.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/cli/connection_monitor.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/connection.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/exceptions.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/gripper/__init__.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/gripper/presets.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/gripper/robotiq_preamble.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/io.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit/telemetry.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit.egg-info/SOURCES.txt +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit.egg-info/dependency_links.txt +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit.egg-info/entry_points.txt +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit.egg-info/requires.txt +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/src/urkit.egg-info/top_level.txt +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/tests/test_exceptions.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/tests/test_geometry.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/tests/test_gripper.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/tests/test_gripper_factory.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/tests/test_gripper_presets.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/tests/test_points.py +0 -0
- {urkit-0.3.0 → urkit-0.3.3}/tests/test_robot_integration.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: urkit
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Universal Robots e-Series control toolkit built on ur_rtde
|
|
5
5
|
Author: URKit Contributors
|
|
6
6
|
License: MIT
|
|
@@ -52,6 +52,7 @@ Built on [`ur_rtde`](https://sdurobotics.gitlab.io/ur_rtde/), it packages the op
|
|
|
52
52
|
- [Raw RTDE Access](#raw-rtde-access)
|
|
53
53
|
- [Connection Lifecycle](#connection-lifecycle)
|
|
54
54
|
- [Error Handling](#error-handling)
|
|
55
|
+
- [Changelog](#changelog)
|
|
55
56
|
|
|
56
57
|
---
|
|
57
58
|
|
|
@@ -189,13 +190,16 @@ All movement and orientation keys support **hold-to-repeat**.
|
|
|
189
190
|
<tr><td><code>X</code></td><td>Open</td></tr>
|
|
190
191
|
<tr><td><code>C</code></td><td>Close</td></tr>
|
|
191
192
|
<tr><td><code>V</code></td><td>Set position (mm)</td></tr>
|
|
193
|
+
<tr><td><code>6</code></td><td>Set speed (0-100)</td></tr>
|
|
194
|
+
<tr><td><code>7</code></td><td>Set force (0-100)</td></tr>
|
|
195
|
+
<tr><td colspan="3">Gripper line shows: `Connected 50.0mm (0%) F=100 S=100`</td></tr>
|
|
192
196
|
</table>
|
|
193
197
|
</td>
|
|
194
198
|
<td align="center" style="width:33%">
|
|
195
199
|
<table>
|
|
196
200
|
<tr><th>Key</th><th>Action</th></tr>
|
|
197
201
|
<tr><td><code>B</code></td><td><strong>Save</strong> current position</td></tr>
|
|
198
|
-
<tr><td><code>G</code></td><td>Go to saved point</td></tr>
|
|
202
|
+
<tr><td><code>G</code></td><td>Go to saved point (<code>Space</code> to cancel mid-move, <code>ESC</code> to exit)</td></tr>
|
|
199
203
|
<tr><td><code>H</code></td><td>Delete saved point</td></tr>
|
|
200
204
|
<tr><td><code>P</code></td><td>Open points explorer</td></tr>
|
|
201
205
|
<tr><td><code>R</code></td><td>Rename saved point</td></tr>
|
|
@@ -215,6 +219,35 @@ All movement and orientation keys support **hold-to-repeat**.
|
|
|
215
219
|
</tr>
|
|
216
220
|
</table>
|
|
217
221
|
|
|
222
|
+
### Joint Display
|
|
223
|
+
|
|
224
|
+
The teach pendant shows live joint angles alongside TCP position and orientation:
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
Position X=+0.432 Y=+0.111 Z=+0.227
|
|
228
|
+
Orientation R=+131.3 P=-121.0 Y= +8.0
|
|
229
|
+
Joints J1=+150.0 J2=+020.0 J3=+160.0
|
|
230
|
+
J4=+050.0 J5=-080.0 J6=+157.0
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Joint angles color-code proximity to mechanical limits:
|
|
234
|
+
|
|
235
|
+
- **Yellow**: within 10% of joint range (warning)
|
|
236
|
+
- **Red**: within 5% of joint range (danger)
|
|
237
|
+
|
|
238
|
+
UR e-Series joint limits:
|
|
239
|
+
|
|
240
|
+
| Joint | Range | Notes |
|
|
241
|
+
|-------|-------|-------|
|
|
242
|
+
| J1 (shoulder pan) | ±360° | Full rotation |
|
|
243
|
+
| J2 (shoulder lift) | ±360° | Full rotation |
|
|
244
|
+
| J3 (elbow) | ±180° | Physically restricted — shoulder lift gets in the way |
|
|
245
|
+
| J4 (wrist 1) | ±360° | Full rotation |
|
|
246
|
+
| J5 (wrist 2) | ±360° | Full rotation |
|
|
247
|
+
| J6 (wrist 3) | ±360° | Tool flange unlimited rotation |
|
|
248
|
+
|
|
249
|
+
Thresholds scale with each joint's range, so warning zones feel proportional across all joints.
|
|
250
|
+
|
|
218
251
|
### Safety
|
|
219
252
|
|
|
220
253
|
By default, **Go To** and **TCP Down** movements use a slow velocity (0.125 m/s) so its safer for anyone standing near the robot. The user's speed slider still applies as a global multiplier on top of this.
|
|
@@ -325,10 +358,34 @@ robot.points_db = "points.db"
|
|
|
325
358
|
robot.move_to("pick") # linear move (default)
|
|
326
359
|
robot.move_to("pick", linear=False) # joint move
|
|
327
360
|
robot.move_to("pick", vel=1.0, acc=0.5) # override speed
|
|
361
|
+
robot.move_to("pick", asynchronous=True) # non-blocking, returns immediately
|
|
328
362
|
```
|
|
329
363
|
|
|
330
364
|
- **Linear (moveL):** TCP moves in a straight line. Predictable path, slower near complex orientations.
|
|
331
365
|
- **Joint (moveJ):** Each joint moves simultaneously. Faster, but the TCP follows an arc.
|
|
366
|
+
- **Asynchronous:** When `asynchronous=True`, the move runs in the UR controller's background thread and the method returns immediately.
|
|
367
|
+
|
|
368
|
+
#### Non-Blocking Moves
|
|
369
|
+
|
|
370
|
+
Start a move and do other things while it runs:
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
robot.move_to("pick", asynchronous=True)
|
|
374
|
+
|
|
375
|
+
# Poll until done
|
|
376
|
+
while robot.is_moving():
|
|
377
|
+
time.sleep(0.01)
|
|
378
|
+
|
|
379
|
+
# Or cancel mid-move
|
|
380
|
+
robot.move_to("pick", asynchronous=True)
|
|
381
|
+
while robot.is_moving():
|
|
382
|
+
if should_cancel:
|
|
383
|
+
robot.stop() # sends stopL + stopJ
|
|
384
|
+
break
|
|
385
|
+
time.sleep(0.01)
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Teach pendant Go To** uses this pattern internally — Space cancels the move and returns to the menu.
|
|
332
389
|
|
|
333
390
|
#### Pose Format
|
|
334
391
|
|
|
@@ -420,6 +477,7 @@ robot.is_freedrive_active # check state
|
|
|
420
477
|
#### Speed Control
|
|
421
478
|
|
|
422
479
|
```python
|
|
480
|
+
robot.stop() # stop current move immediately (stopL + stopJ)
|
|
423
481
|
robot.speed_stop() # stop velocity-controlled motion (not E-stop)
|
|
424
482
|
robot.set_speed_slider(0.5) # 50% velocity cap
|
|
425
483
|
robot.get_speed_slider() # read current slider (0.0-1.0)
|
|
@@ -441,9 +499,26 @@ joints = robot.get_joint_positions() # [j0..j5]
|
|
|
441
499
|
force = robot.get_tcp_force() # [fx, fy, fz, mx, my, mz]
|
|
442
500
|
mode = robot.get_robot_mode() # "REMOTE_CONTROL", "SERVOING", etc.
|
|
443
501
|
payload = robot.get_payload() # kg
|
|
502
|
+
robot.is_moving() # bool — any joint/TCP velocity non-zero
|
|
444
503
|
robot.is_protective_stopped() # bool
|
|
445
504
|
robot.is_emergency_stopped() # bool
|
|
446
505
|
robot.current_point() # {"pose": [...], "joints": [...]}
|
|
506
|
+
robot.is_at_pose(target) # bool — TCP within 1mm / 0.5°
|
|
507
|
+
robot.is_at_joints(target) # bool — all joints within 0.001 rad
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
`is_moving()` is the simplest way to poll — `is_at_pose()` / `is_at_joints()` for precise target checking:
|
|
511
|
+
|
|
512
|
+
```python
|
|
513
|
+
robot.move_to("pick", asynchronous=True)
|
|
514
|
+
|
|
515
|
+
# Simple: wait until robot stops
|
|
516
|
+
while robot.is_moving():
|
|
517
|
+
time.sleep(0.01)
|
|
518
|
+
|
|
519
|
+
# Precise: check against specific target
|
|
520
|
+
while not robot.is_at_pose(target_pose):
|
|
521
|
+
time.sleep(0.01)
|
|
447
522
|
```
|
|
448
523
|
|
|
449
524
|
### Digital I/O
|
|
@@ -588,3 +663,20 @@ When the robot enters protective stop or the RTDE connection drops, motion comma
|
|
|
588
663
|
### Connection Notes
|
|
589
664
|
|
|
590
665
|
The `URRobot` constructor takes a few seconds on first call: it validates the connection, checks remote mode, powers on the robot, releases brakes, and connects RTDE. Subsequent calls are faster if the robot is already running.
|
|
666
|
+
|
|
667
|
+
---
|
|
668
|
+
|
|
669
|
+
## Changelog
|
|
670
|
+
|
|
671
|
+
See [CHANGELOG.md](CHANGELOG.md) for the full version history.
|
|
672
|
+
|
|
673
|
+
### Recent Changes
|
|
674
|
+
|
|
675
|
+
- **v0.3.2** — Gripper speed/force keys (6/7), force/speed display
|
|
676
|
+
- **v0.3.1** — Async motion, Space cancel, progress bar, joint display
|
|
677
|
+
- **v0.3.0** — Safe/expert mode, speed_stop on exit, safety features
|
|
678
|
+
- **v0.2.1** — `get_pose()` method
|
|
679
|
+
- **v0.2.0** — README restructure
|
|
680
|
+
- **v0.1.1** — `--gripper none`, `--config` flag, save config on demand
|
|
681
|
+
- **v0.1.0** — Initial release
|
|
682
|
+
|
|
@@ -26,6 +26,7 @@ Built on [`ur_rtde`](https://sdurobotics.gitlab.io/ur_rtde/), it packages the op
|
|
|
26
26
|
- [Raw RTDE Access](#raw-rtde-access)
|
|
27
27
|
- [Connection Lifecycle](#connection-lifecycle)
|
|
28
28
|
- [Error Handling](#error-handling)
|
|
29
|
+
- [Changelog](#changelog)
|
|
29
30
|
|
|
30
31
|
---
|
|
31
32
|
|
|
@@ -163,13 +164,16 @@ All movement and orientation keys support **hold-to-repeat**.
|
|
|
163
164
|
<tr><td><code>X</code></td><td>Open</td></tr>
|
|
164
165
|
<tr><td><code>C</code></td><td>Close</td></tr>
|
|
165
166
|
<tr><td><code>V</code></td><td>Set position (mm)</td></tr>
|
|
167
|
+
<tr><td><code>6</code></td><td>Set speed (0-100)</td></tr>
|
|
168
|
+
<tr><td><code>7</code></td><td>Set force (0-100)</td></tr>
|
|
169
|
+
<tr><td colspan="3">Gripper line shows: `Connected 50.0mm (0%) F=100 S=100`</td></tr>
|
|
166
170
|
</table>
|
|
167
171
|
</td>
|
|
168
172
|
<td align="center" style="width:33%">
|
|
169
173
|
<table>
|
|
170
174
|
<tr><th>Key</th><th>Action</th></tr>
|
|
171
175
|
<tr><td><code>B</code></td><td><strong>Save</strong> current position</td></tr>
|
|
172
|
-
<tr><td><code>G</code></td><td>Go to saved point</td></tr>
|
|
176
|
+
<tr><td><code>G</code></td><td>Go to saved point (<code>Space</code> to cancel mid-move, <code>ESC</code> to exit)</td></tr>
|
|
173
177
|
<tr><td><code>H</code></td><td>Delete saved point</td></tr>
|
|
174
178
|
<tr><td><code>P</code></td><td>Open points explorer</td></tr>
|
|
175
179
|
<tr><td><code>R</code></td><td>Rename saved point</td></tr>
|
|
@@ -189,6 +193,35 @@ All movement and orientation keys support **hold-to-repeat**.
|
|
|
189
193
|
</tr>
|
|
190
194
|
</table>
|
|
191
195
|
|
|
196
|
+
### Joint Display
|
|
197
|
+
|
|
198
|
+
The teach pendant shows live joint angles alongside TCP position and orientation:
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
Position X=+0.432 Y=+0.111 Z=+0.227
|
|
202
|
+
Orientation R=+131.3 P=-121.0 Y= +8.0
|
|
203
|
+
Joints J1=+150.0 J2=+020.0 J3=+160.0
|
|
204
|
+
J4=+050.0 J5=-080.0 J6=+157.0
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Joint angles color-code proximity to mechanical limits:
|
|
208
|
+
|
|
209
|
+
- **Yellow**: within 10% of joint range (warning)
|
|
210
|
+
- **Red**: within 5% of joint range (danger)
|
|
211
|
+
|
|
212
|
+
UR e-Series joint limits:
|
|
213
|
+
|
|
214
|
+
| Joint | Range | Notes |
|
|
215
|
+
|-------|-------|-------|
|
|
216
|
+
| J1 (shoulder pan) | ±360° | Full rotation |
|
|
217
|
+
| J2 (shoulder lift) | ±360° | Full rotation |
|
|
218
|
+
| J3 (elbow) | ±180° | Physically restricted — shoulder lift gets in the way |
|
|
219
|
+
| J4 (wrist 1) | ±360° | Full rotation |
|
|
220
|
+
| J5 (wrist 2) | ±360° | Full rotation |
|
|
221
|
+
| J6 (wrist 3) | ±360° | Tool flange unlimited rotation |
|
|
222
|
+
|
|
223
|
+
Thresholds scale with each joint's range, so warning zones feel proportional across all joints.
|
|
224
|
+
|
|
192
225
|
### Safety
|
|
193
226
|
|
|
194
227
|
By default, **Go To** and **TCP Down** movements use a slow velocity (0.125 m/s) so its safer for anyone standing near the robot. The user's speed slider still applies as a global multiplier on top of this.
|
|
@@ -299,10 +332,34 @@ robot.points_db = "points.db"
|
|
|
299
332
|
robot.move_to("pick") # linear move (default)
|
|
300
333
|
robot.move_to("pick", linear=False) # joint move
|
|
301
334
|
robot.move_to("pick", vel=1.0, acc=0.5) # override speed
|
|
335
|
+
robot.move_to("pick", asynchronous=True) # non-blocking, returns immediately
|
|
302
336
|
```
|
|
303
337
|
|
|
304
338
|
- **Linear (moveL):** TCP moves in a straight line. Predictable path, slower near complex orientations.
|
|
305
339
|
- **Joint (moveJ):** Each joint moves simultaneously. Faster, but the TCP follows an arc.
|
|
340
|
+
- **Asynchronous:** When `asynchronous=True`, the move runs in the UR controller's background thread and the method returns immediately.
|
|
341
|
+
|
|
342
|
+
#### Non-Blocking Moves
|
|
343
|
+
|
|
344
|
+
Start a move and do other things while it runs:
|
|
345
|
+
|
|
346
|
+
```python
|
|
347
|
+
robot.move_to("pick", asynchronous=True)
|
|
348
|
+
|
|
349
|
+
# Poll until done
|
|
350
|
+
while robot.is_moving():
|
|
351
|
+
time.sleep(0.01)
|
|
352
|
+
|
|
353
|
+
# Or cancel mid-move
|
|
354
|
+
robot.move_to("pick", asynchronous=True)
|
|
355
|
+
while robot.is_moving():
|
|
356
|
+
if should_cancel:
|
|
357
|
+
robot.stop() # sends stopL + stopJ
|
|
358
|
+
break
|
|
359
|
+
time.sleep(0.01)
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Teach pendant Go To** uses this pattern internally — Space cancels the move and returns to the menu.
|
|
306
363
|
|
|
307
364
|
#### Pose Format
|
|
308
365
|
|
|
@@ -394,6 +451,7 @@ robot.is_freedrive_active # check state
|
|
|
394
451
|
#### Speed Control
|
|
395
452
|
|
|
396
453
|
```python
|
|
454
|
+
robot.stop() # stop current move immediately (stopL + stopJ)
|
|
397
455
|
robot.speed_stop() # stop velocity-controlled motion (not E-stop)
|
|
398
456
|
robot.set_speed_slider(0.5) # 50% velocity cap
|
|
399
457
|
robot.get_speed_slider() # read current slider (0.0-1.0)
|
|
@@ -415,9 +473,26 @@ joints = robot.get_joint_positions() # [j0..j5]
|
|
|
415
473
|
force = robot.get_tcp_force() # [fx, fy, fz, mx, my, mz]
|
|
416
474
|
mode = robot.get_robot_mode() # "REMOTE_CONTROL", "SERVOING", etc.
|
|
417
475
|
payload = robot.get_payload() # kg
|
|
476
|
+
robot.is_moving() # bool — any joint/TCP velocity non-zero
|
|
418
477
|
robot.is_protective_stopped() # bool
|
|
419
478
|
robot.is_emergency_stopped() # bool
|
|
420
479
|
robot.current_point() # {"pose": [...], "joints": [...]}
|
|
480
|
+
robot.is_at_pose(target) # bool — TCP within 1mm / 0.5°
|
|
481
|
+
robot.is_at_joints(target) # bool — all joints within 0.001 rad
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
`is_moving()` is the simplest way to poll — `is_at_pose()` / `is_at_joints()` for precise target checking:
|
|
485
|
+
|
|
486
|
+
```python
|
|
487
|
+
robot.move_to("pick", asynchronous=True)
|
|
488
|
+
|
|
489
|
+
# Simple: wait until robot stops
|
|
490
|
+
while robot.is_moving():
|
|
491
|
+
time.sleep(0.01)
|
|
492
|
+
|
|
493
|
+
# Precise: check against specific target
|
|
494
|
+
while not robot.is_at_pose(target_pose):
|
|
495
|
+
time.sleep(0.01)
|
|
421
496
|
```
|
|
422
497
|
|
|
423
498
|
### Digital I/O
|
|
@@ -562,3 +637,20 @@ When the robot enters protective stop or the RTDE connection drops, motion comma
|
|
|
562
637
|
### Connection Notes
|
|
563
638
|
|
|
564
639
|
The `URRobot` constructor takes a few seconds on first call: it validates the connection, checks remote mode, powers on the robot, releases brakes, and connects RTDE. Subsequent calls are faster if the robot is already running.
|
|
640
|
+
|
|
641
|
+
---
|
|
642
|
+
|
|
643
|
+
## Changelog
|
|
644
|
+
|
|
645
|
+
See [CHANGELOG.md](CHANGELOG.md) for the full version history.
|
|
646
|
+
|
|
647
|
+
### Recent Changes
|
|
648
|
+
|
|
649
|
+
- **v0.3.2** — Gripper speed/force keys (6/7), force/speed display
|
|
650
|
+
- **v0.3.1** — Async motion, Space cancel, progress bar, joint display
|
|
651
|
+
- **v0.3.0** — Safe/expert mode, speed_stop on exit, safety features
|
|
652
|
+
- **v0.2.1** — `get_pose()` method
|
|
653
|
+
- **v0.2.0** — README restructure
|
|
654
|
+
- **v0.1.1** — `--gripper none`, `--config` flag, save config on demand
|
|
655
|
+
- **v0.1.0** — Initial release
|
|
656
|
+
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "urkit"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.3"
|
|
8
8
|
description = "Universal Robots e-Series control toolkit built on ur_rtde"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -71,3 +71,7 @@ line-length = 99
|
|
|
71
71
|
|
|
72
72
|
[tool.ruff.lint]
|
|
73
73
|
select = ["E", "F", "I", "N", "W", "UP"]
|
|
74
|
+
|
|
75
|
+
[tool.mypy]
|
|
76
|
+
follow_imports = "skip"
|
|
77
|
+
ignore_missing_imports = true
|
|
@@ -73,7 +73,7 @@ def _explore_points(args) -> None:
|
|
|
73
73
|
# Resolve points path
|
|
74
74
|
config = load_config()
|
|
75
75
|
points_path = args.points_path or config.get("points_path") or "points.db"
|
|
76
|
-
points_path = Path(points_path).resolve()
|
|
76
|
+
points_path = Path(points_path).resolve() # type: ignore
|
|
77
77
|
|
|
78
78
|
if not points_path.exists():
|
|
79
79
|
print(f"Error: Points database not found: {points_path}")
|
|
@@ -126,8 +126,6 @@ def _interactive_points_filter(points_db: Points, all_points: list[str], points_
|
|
|
126
126
|
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, new_settings)
|
|
127
127
|
|
|
128
128
|
fd = sys.stdin.fileno()
|
|
129
|
-
# Rich auto-detects dark/light terminal theme
|
|
130
|
-
console = Console(force_terminal=True)
|
|
131
129
|
|
|
132
130
|
try:
|
|
133
131
|
while True:
|
|
@@ -276,25 +274,6 @@ def _interactive_points_filter(points_db: Points, all_points: list[str], points_
|
|
|
276
274
|
filter_str = filter_str[:-1]
|
|
277
275
|
scroll = 0
|
|
278
276
|
needs_redraw = True
|
|
279
|
-
elif ch == "\r": # Enter — reload points from database
|
|
280
|
-
if not points_path.exists():
|
|
281
|
-
refresh_error = "Database file deleted"
|
|
282
|
-
all_points = []
|
|
283
|
-
all_points_sorted = []
|
|
284
|
-
filtered = []
|
|
285
|
-
scroll = 0
|
|
286
|
-
needs_redraw = True
|
|
287
|
-
else:
|
|
288
|
-
try:
|
|
289
|
-
all_points = points_db.list()
|
|
290
|
-
refresh_error = None
|
|
291
|
-
all_points_sorted = sorted(all_points)
|
|
292
|
-
filtered = [p for p in all_points_sorted if filter_str == "" or filter_str.lower() in p.lower()]
|
|
293
|
-
scroll = 0
|
|
294
|
-
needs_redraw = True
|
|
295
|
-
except Exception as e:
|
|
296
|
-
refresh_error = str(e)
|
|
297
|
-
needs_redraw = True
|
|
298
277
|
elif ch.isprintable():
|
|
299
278
|
filter_str += ch
|
|
300
279
|
scroll = 0
|