pairling 0.0.1 → 0.1.0

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 (61) hide show
  1. package/package.json +5 -1
  2. package/payload/mac/SOURCE_BRANCH +1 -0
  3. package/payload/mac/SOURCE_DIRTY +1 -0
  4. package/payload/mac/SOURCE_REVISION +1 -0
  5. package/payload/mac/VERSION +1 -0
  6. package/payload/mac/companiond/integrations/__init__.py +1 -0
  7. package/payload/mac/companiond/integrations/aperture_cli/__init__.py +23 -0
  8. package/payload/mac/companiond/integrations/aperture_cli/launch.py +456 -0
  9. package/payload/mac/companiond/integrations/aperture_cli/status.py +393 -0
  10. package/payload/mac/companiond/live_activity_publisher.py +380 -0
  11. package/payload/mac/companiond/llm_route.py +108 -0
  12. package/payload/mac/companiond/local_mcp_bridge.py +156 -0
  13. package/payload/mac/companiond/model_status_contract.py +101 -0
  14. package/payload/mac/companiond/pairdrop_store.py +920 -0
  15. package/payload/mac/companiond/pairling_connectd_status.py +149 -0
  16. package/payload/mac/companiond/pairling_devices.py +459 -0
  17. package/payload/mac/companiond/pairling_pairing.py +404 -0
  18. package/payload/mac/companiond/pairling_relay_claims.py +232 -0
  19. package/payload/mac/companiond/pairling_tools.py +706 -0
  20. package/payload/mac/companiond/pairlingd.py +18438 -0
  21. package/payload/mac/companiond/providers/__init__.py +1 -0
  22. package/payload/mac/companiond/providers/base.py +255 -0
  23. package/payload/mac/companiond/providers/claude.py +127 -0
  24. package/payload/mac/companiond/providers/codex.py +124 -0
  25. package/payload/mac/companiond/providers/external.py +46 -0
  26. package/payload/mac/companiond/providers/registry.py +70 -0
  27. package/payload/mac/companiond/pty_broker.py +887 -0
  28. package/payload/mac/companiond/push_dispatcher.py +1990 -0
  29. package/payload/mac/companiond/push_event_catalog.py +566 -0
  30. package/payload/mac/companiond/request_proof.py +142 -0
  31. package/payload/mac/companiond/runtime_contract.py +47 -0
  32. package/payload/mac/companiond/runtime_manifest.py +197 -0
  33. package/payload/mac/companiond/runtime_paths.py +87 -0
  34. package/payload/mac/companiond/safety_monitor.py +542 -0
  35. package/payload/mac/companiond/sentinel_notifications.py +491 -0
  36. package/payload/mac/companiond/standard_push_publisher.py +516 -0
  37. package/payload/mac/companiond/substrate_status_contract.py +139 -0
  38. package/payload/mac/companiond/terminal_screen_backend.py +332 -0
  39. package/payload/mac/companiond/terminal_text_sanitizer.py +54 -0
  40. package/payload/mac/companiond/workstate_feed_contract.py +108 -0
  41. package/payload/mac/connectd/cmd/pairling-connectd/auth_open_test.go +116 -0
  42. package/payload/mac/connectd/cmd/pairling-connectd/main.go +345 -0
  43. package/payload/mac/connectd/cmd/pairling-connectd/upstream_health_test.go +33 -0
  44. package/payload/mac/connectd/go.mod +51 -0
  45. package/payload/mac/connectd/go.sum +229 -0
  46. package/payload/mac/connectd/internal/gateway/proxy.go +597 -0
  47. package/payload/mac/connectd/internal/gateway/proxy_test.go +531 -0
  48. package/payload/mac/connectd/internal/runtime/config.go +99 -0
  49. package/payload/mac/connectd/internal/runtime/config_test.go +29 -0
  50. package/payload/mac/connectd/internal/status/status.go +300 -0
  51. package/payload/mac/connectd/internal/status/status_test.go +263 -0
  52. package/payload/mac/guardian/companion-power-guardian.py +613 -0
  53. package/payload/mac/guardian/guardian_contract.py +67 -0
  54. package/payload/mac/install/bootstrap-first-run.sh +206 -0
  55. package/payload/mac/install/doctor.sh +660 -0
  56. package/payload/mac/install/install-runtime.sh +1241 -0
  57. package/payload/mac/install/render-launchd.py +119 -0
  58. package/payload/mac/install/uninstall-runtime.sh +136 -0
  59. package/payload/mac/mcp/phone_tools.py +210 -0
  60. package/payload/mac/packaging/bin/pairling +63 -0
  61. package/payload-manifest.json +255 -0
@@ -0,0 +1,101 @@
1
+ """Read-only model arbiter status contract for the Pairling Mac daemon."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import subprocess
8
+ from pathlib import Path
9
+ from typing import Mapping
10
+
11
+
12
+ DEFAULT_SINCE = "0000-01-01T00:00:00.000Z"
13
+ DEFAULT_LIMIT = 50
14
+ DEFAULT_MAX_LIMIT = 200
15
+ DEFAULT_ORGANIZER_BIN = str(Path.home() / "projects" / "metal-perception-memory-substrate" / "organizer")
16
+ DEFAULT_ORGANIZER_CONFIG = str(Path.home() / "projects" / "metal-perception-memory-substrate" / "organizer.yaml")
17
+
18
+
19
+ class ModelStatusError(ValueError):
20
+ pass
21
+
22
+
23
+ def _env(env: Mapping[str, str] | None) -> Mapping[str, str]:
24
+ return os.environ if env is None else env
25
+
26
+
27
+ def model_status_max_limit(env: Mapping[str, str] | None = None) -> int:
28
+ current_env = _env(env)
29
+ try:
30
+ value = int(current_env.get("COMPANION_MODEL_STATUS_MAX_LIMIT", str(DEFAULT_MAX_LIMIT)))
31
+ except ValueError:
32
+ return DEFAULT_MAX_LIMIT
33
+ return max(1, min(value, 1000))
34
+
35
+
36
+ def organizer_bin(env: Mapping[str, str] | None = None) -> str:
37
+ return _env(env).get("MODEL_ARBITER_ORGANIZER_BIN") or DEFAULT_ORGANIZER_BIN
38
+
39
+
40
+ def organizer_config(env: Mapping[str, str] | None = None) -> str:
41
+ return _env(env).get("MODEL_ARBITER_ORGANIZER_CONFIG") or DEFAULT_ORGANIZER_CONFIG
42
+
43
+
44
+ def build_model_status_command(
45
+ run: str | Path,
46
+ since: str = DEFAULT_SINCE,
47
+ limit: int = DEFAULT_LIMIT,
48
+ *,
49
+ organizer: str | None = None,
50
+ config: str | None = None,
51
+ env: Mapping[str, str] | None = None,
52
+ ) -> list[str]:
53
+ if not str(run).strip():
54
+ raise ModelStatusError("run is required")
55
+ if limit <= 0:
56
+ raise ModelStatusError("limit must be positive")
57
+
58
+ current_limit = min(limit, model_status_max_limit(env))
59
+ return [
60
+ organizer or organizer_bin(env),
61
+ "--config",
62
+ config or organizer_config(env),
63
+ "model",
64
+ "status",
65
+ "--run",
66
+ str(run),
67
+ "--since",
68
+ since,
69
+ "--limit",
70
+ str(current_limit),
71
+ "--json",
72
+ ]
73
+
74
+
75
+ def fetch_model_status(
76
+ run: str | Path,
77
+ since: str = DEFAULT_SINCE,
78
+ limit: int = DEFAULT_LIMIT,
79
+ *,
80
+ timeout_seconds: float = 5.0,
81
+ env: Mapping[str, str] | None = None,
82
+ ) -> dict:
83
+ command = build_model_status_command(run, since=since, limit=limit, env=env)
84
+ try:
85
+ completed = subprocess.run(command, capture_output=True, text=True, timeout=timeout_seconds, check=False)
86
+ except OSError as exc:
87
+ raise ModelStatusError(f"could not execute model status adapter: {exc}") from exc
88
+ except subprocess.TimeoutExpired as exc:
89
+ raise ModelStatusError("model status adapter timed out") from exc
90
+ if completed.returncode != 0:
91
+ detail = (completed.stderr or completed.stdout or "").strip()[:500]
92
+ raise ModelStatusError(f"model status adapter failed: {detail}")
93
+ try:
94
+ payload = json.loads(completed.stdout)
95
+ except json.JSONDecodeError as exc:
96
+ raise ModelStatusError("model status adapter returned invalid JSON") from exc
97
+ if payload.get("status") != "model_arbiter.readonly.v1" or payload.get("read_only") is not True:
98
+ raise ModelStatusError("model status adapter returned an unexpected contract")
99
+ payload["consumer"] = "pairling"
100
+ payload["adapter"] = "pairling.model_status"
101
+ return payload