pocketshell 0.4.12__tar.gz → 0.4.13__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.
- {pocketshell-0.4.12 → pocketshell-0.4.13}/PKG-INFO +1 -1
- {pocketshell-0.4.12 → pocketshell-0.4.13}/pyproject.toml +1 -1
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/agents.py +47 -15
- pocketshell-0.4.13/src/pocketshell/cards.py +663 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/cli.py +5 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/tree.py +23 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_agents.py +166 -2
- pocketshell-0.4.13/tests/test_cards.py +391 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_tree.py +31 -1
- {pocketshell-0.4.12 → pocketshell-0.4.13}/uv.lock +2 -2
- {pocketshell-0.4.12 → pocketshell-0.4.13}/.gitignore +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/README.md +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/scheduler/README.md +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/scheduler/pocketshell-usage-capture.service +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/scheduler/pocketshell-usage-capture.timer +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/__init__.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/__main__.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/agent_log.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/agents_kind.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/cgroup_agents.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/daemon.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/env.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/github.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/hooks.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/jobs.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/logs.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/profiles.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/prune_attachments.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/push.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/qr_share.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/repos.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/resume.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/sessions.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/usage.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/usage_capture.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/src/pocketshell/usage_reset.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/__init__.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_agent_log.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_agents_kind.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_cgroup_agents.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_cli.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_daemon.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_env.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_github.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_hooks.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_jobs.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_logs.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_profiles.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_prune_attachments.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_push.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_qr_share.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_repos.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_resume.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_sessions.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_usage.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_usage_capture.py +0 -0
- {pocketshell-0.4.12 → pocketshell-0.4.13}/tests/test_usage_reset.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pocketshell
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.13
|
|
4
4
|
Summary: Unified server-side Python utility for the PocketShell Android client.
|
|
5
5
|
Project-URL: Homepage, https://github.com/alexeygrigorev/pocketshell
|
|
6
6
|
Project-URL: Issues, https://github.com/alexeygrigorev/pocketshell/issues
|
|
@@ -8,7 +8,7 @@ name = "pocketshell"
|
|
|
8
8
|
# scripts/check-pypi-version.sh enforces this; .github/workflows/build.yml
|
|
9
9
|
# runs that check before publishing to PyPI. See
|
|
10
10
|
# tools/pocketshell/README.md ("Release flow") for the bump procedure.
|
|
11
|
-
version = "0.4.
|
|
11
|
+
version = "0.4.13"
|
|
12
12
|
description = "Unified server-side Python utility for the PocketShell Android client."
|
|
13
13
|
readme = "README.md"
|
|
14
14
|
requires-python = ">=3.11"
|
|
@@ -359,6 +359,7 @@ def record_agent_kind(
|
|
|
359
359
|
kind: str,
|
|
360
360
|
env: Optional[dict[str, str]] = None,
|
|
361
361
|
runner=None,
|
|
362
|
+
profile: Optional[str] = None,
|
|
362
363
|
) -> bool:
|
|
363
364
|
"""Record the launched agent ``kind`` as a per-session tmux user option.
|
|
364
365
|
|
|
@@ -371,10 +372,20 @@ def record_agent_kind(
|
|
|
371
372
|
change. The client reads it back through its session enumeration
|
|
372
373
|
(``tmux list-sessions -F '…#{@ps_agent_kind}'``).
|
|
373
374
|
|
|
374
|
-
|
|
375
|
+
``profile`` (issue #858) is the human label of the *non-default* profile
|
|
376
|
+
the agent was launched with — e.g. ``"Claude (Z.AI)"`` for a z.ai Claude
|
|
377
|
+
session, so the tree can distinguish it from a default Anthropic Claude.
|
|
378
|
+
It is the same launch-time-recordable dimension as the kind (the selected
|
|
379
|
+
profile name is known here, before ``os.execvpe``; #826 record-at-start
|
|
380
|
+
hard-cut — no detection/parse path). When set, it is written as the
|
|
381
|
+
per-session ``@ps_agent_profile`` user option alongside ``@ps_agent_kind``.
|
|
382
|
+
A default / no-profile launch passes ``None`` and writes NO profile
|
|
383
|
+
option, so a default session carries no spurious profile label.
|
|
384
|
+
|
|
385
|
+
The options are session-scoped (not global): ``tmux set-option`` without
|
|
375
386
|
``-g`` sets it on the current session, which is the session the agent
|
|
376
387
|
was launched into. tmux session options persist for the life of the
|
|
377
|
-
session, so the recorded kind survives reconnect / app restart /
|
|
388
|
+
session, so the recorded kind/profile survives reconnect / app restart /
|
|
378
389
|
app-kill / reinstall — exactly the durability the epic requires.
|
|
379
390
|
|
|
380
391
|
No-op (returns ``False``) when not running inside tmux (``$TMUX``
|
|
@@ -399,6 +410,13 @@ def record_agent_kind(
|
|
|
399
410
|
["tmux", "set-option", "@ps_agent_kind", kind],
|
|
400
411
|
check=False,
|
|
401
412
|
)
|
|
413
|
+
if profile:
|
|
414
|
+
# Only a non-default profile is recorded; a default/no-profile
|
|
415
|
+
# launch writes no option so the tree shows the plain kind.
|
|
416
|
+
runner(
|
|
417
|
+
["tmux", "set-option", "@ps_agent_profile", profile],
|
|
418
|
+
check=False,
|
|
419
|
+
)
|
|
402
420
|
except Exception:
|
|
403
421
|
# Recording the kind is best-effort; never block the launch on it.
|
|
404
422
|
return False
|
|
@@ -413,6 +431,7 @@ def launch_agent(
|
|
|
413
431
|
skip_permissions: bool,
|
|
414
432
|
config_dir: Optional[str],
|
|
415
433
|
extra_env: Optional[dict[str, str]] = None,
|
|
434
|
+
profile: Optional[str] = None,
|
|
416
435
|
execvpe=None,
|
|
417
436
|
record_kind=None,
|
|
418
437
|
) -> None:
|
|
@@ -422,6 +441,11 @@ def launch_agent(
|
|
|
422
441
|
#732); it layers onto the launch environment under the #703 provider
|
|
423
442
|
strip (see :func:`build_env`).
|
|
424
443
|
|
|
444
|
+
``profile`` (issue #858) is the human label of the *non-default* profile
|
|
445
|
+
the launch used (``None`` for the engine default). It is recorded
|
|
446
|
+
alongside the kind as the ``@ps_agent_profile`` tmux user option so the
|
|
447
|
+
session tree can distinguish e.g. a z.ai Claude from a default Claude.
|
|
448
|
+
|
|
425
449
|
``execvpe`` is injected so tests can assert the exact call without
|
|
426
450
|
actually replacing the process. When ``None`` (production) it resolves
|
|
427
451
|
to :func:`os.execvpe` *at call time* — looking it up on the module's
|
|
@@ -473,7 +497,7 @@ def launch_agent(
|
|
|
473
497
|
# this process (epic #821 Workstream A). Use this wrapper's own
|
|
474
498
|
# environment (os.environ) for the TMUX detection — `env` is the
|
|
475
499
|
# provider-stripped launch env that does not necessarily carry $TMUX.
|
|
476
|
-
record_kind(kind, dict(os.environ))
|
|
500
|
+
record_kind(kind, dict(os.environ), profile=profile)
|
|
477
501
|
|
|
478
502
|
# Replace this process with the agent so it owns the pty cleanly.
|
|
479
503
|
execvpe(argv[0], argv, env)
|
|
@@ -484,17 +508,21 @@ def _resolve_config_dir(
|
|
|
484
508
|
kind: str,
|
|
485
509
|
config_dir: Optional[str],
|
|
486
510
|
profile: Optional[str],
|
|
487
|
-
) -> tuple[Optional[str], dict[str, str]]:
|
|
488
|
-
"""Resolve config dir + extra env from
|
|
511
|
+
) -> tuple[Optional[str], dict[str, str], Optional[str]]:
|
|
512
|
+
"""Resolve config dir + extra env + profile label from the launch flags.
|
|
489
513
|
|
|
490
|
-
Returns ``(config_dir, extra_env)``. ``--config-dir`` and
|
|
491
|
-
are mutually exclusive (passing both is an error). When
|
|
492
|
-
given, it resolves the named host profile (via
|
|
514
|
+
Returns ``(config_dir, extra_env, profile_label)``. ``--config-dir`` and
|
|
515
|
+
``--profile`` are mutually exclusive (passing both is an error). When
|
|
516
|
+
``--profile`` is given, it resolves the named host profile (via
|
|
493
517
|
:func:`pocketshell.profiles.resolve_profile`) to its ``config_dir`` AND
|
|
494
|
-
its ``env:`` block (issue #732) — an unknown profile is a clear error.
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
518
|
+
its ``env:`` block (issue #732) — an unknown profile is a clear error.
|
|
519
|
+
|
|
520
|
+
``profile_label`` (issue #858) is the resolved profile's human ``name``
|
|
521
|
+
for a *non-default* profile (e.g. ``"Claude (Z.AI)"``), so the session
|
|
522
|
+
tree can tell a z.ai Claude apart from a default Claude. The engine's
|
|
523
|
+
default profile, ``--config-dir`` (which carries no named profile), and
|
|
524
|
+
omitting both flags all resolve ``profile_label`` to ``None`` — so a
|
|
525
|
+
default session records no ``@ps_agent_profile`` option.
|
|
498
526
|
"""
|
|
499
527
|
if config_dir is not None and profile is not None:
|
|
500
528
|
click.echo(
|
|
@@ -504,7 +532,7 @@ def _resolve_config_dir(
|
|
|
504
532
|
)
|
|
505
533
|
ctx.exit(2)
|
|
506
534
|
if profile is None:
|
|
507
|
-
return config_dir, {}
|
|
535
|
+
return config_dir, {}, None
|
|
508
536
|
|
|
509
537
|
# Lazy import keeps the agent launch path from importing yaml unless a
|
|
510
538
|
# profile is actually requested.
|
|
@@ -519,7 +547,10 @@ def _resolve_config_dir(
|
|
|
519
547
|
err=True,
|
|
520
548
|
)
|
|
521
549
|
ctx.exit(2)
|
|
522
|
-
|
|
550
|
+
# Only a non-default profile is surfaced as a label; the default profile
|
|
551
|
+
# is the plain kind (no spurious chip in the tree).
|
|
552
|
+
label = None if resolved.default else resolved.name
|
|
553
|
+
return resolved.config_dir, dict(resolved.env), label
|
|
523
554
|
|
|
524
555
|
|
|
525
556
|
def _make_agent_command(kind: str):
|
|
@@ -575,7 +606,7 @@ def _make_agent_command(kind: str):
|
|
|
575
606
|
config_dir: Optional[str],
|
|
576
607
|
profile: Optional[str],
|
|
577
608
|
) -> None:
|
|
578
|
-
config_dir, extra_env = _resolve_config_dir(
|
|
609
|
+
config_dir, extra_env, profile_label = _resolve_config_dir(
|
|
579
610
|
ctx, kind, config_dir, profile
|
|
580
611
|
)
|
|
581
612
|
launch_agent(
|
|
@@ -585,6 +616,7 @@ def _make_agent_command(kind: str):
|
|
|
585
616
|
skip_permissions=skip_permissions,
|
|
586
617
|
config_dir=config_dir,
|
|
587
618
|
extra_env=extra_env,
|
|
619
|
+
profile=profile_label,
|
|
588
620
|
)
|
|
589
621
|
|
|
590
622
|
return _cmd
|