robopark 3.1.2 → 3.3.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.
- package/README.md +66 -95
- package/bin/robopark.js +9 -2
- package/conversation/elevenlabs_agent.py +1617 -1617
- package/conversation/supervisor_store.py +189 -189
- package/dist/{kernel/config-schema.js → config-schema.js} +1 -0
- package/dist/config-schema.js.map +1 -0
- package/dist/robopark/add-robot.js +1 -0
- package/dist/robopark/add-robot.js.map +1 -0
- package/dist/robopark/agent-ctl.js +1 -0
- package/dist/robopark/agent-ctl.js.map +1 -0
- package/dist/robopark/auto-start.js +51 -73
- package/dist/robopark/auto-start.js.map +1 -0
- package/dist/robopark/conversation.js +1 -0
- package/dist/robopark/conversation.js.map +1 -0
- package/dist/robopark/discovery.js +1 -0
- package/dist/robopark/discovery.js.map +1 -0
- package/dist/robopark/doctor.js +1 -0
- package/dist/robopark/doctor.js.map +1 -0
- package/dist/robopark/enroll.js +1 -0
- package/dist/robopark/enroll.js.map +1 -0
- package/dist/robopark/llm-set.js +1 -0
- package/dist/robopark/llm-set.js.map +1 -0
- package/dist/robopark/motor-control.js +1 -0
- package/dist/robopark/motor-control.js.map +1 -0
- package/dist/robopark/preview-agent-launcher.js +1 -0
- package/dist/robopark/preview-agent-launcher.js.map +1 -0
- package/dist/robopark/probe.js +16 -15
- package/dist/robopark/probe.js.map +1 -0
- package/dist/robopark/profile.js +1 -0
- package/dist/robopark/profile.js.map +1 -0
- package/dist/robopark/python-env.js +1 -7
- package/dist/robopark/python-env.js.map +1 -0
- package/dist/robopark/robot-runtime.js +1 -0
- package/dist/robopark/robot-runtime.js.map +1 -0
- package/dist/robopark/scan.js +1 -0
- package/dist/robopark/scan.js.map +1 -0
- package/dist/robopark/screen-control.js +1 -0
- package/dist/robopark/screen-control.js.map +1 -0
- package/dist/robopark/secrets.js +1 -0
- package/dist/robopark/secrets.js.map +1 -0
- package/dist/robopark/serve.js +4 -6
- package/dist/robopark/serve.js.map +1 -0
- package/dist/robopark/server-add.js +1 -0
- package/dist/robopark/server-add.js.map +1 -0
- package/dist/robopark/setup-livekit.js +53 -52
- package/dist/robopark/setup-livekit.js.map +1 -0
- package/dist/robopark/setup.js +1 -0
- package/dist/robopark/setup.js.map +1 -0
- package/dist/robopark/stop-all.js +1 -0
- package/dist/robopark/stop-all.js.map +1 -0
- package/dist/robopark/verify.js +1 -0
- package/dist/robopark/verify.js.map +1 -0
- package/dist/robopark/vision-agent-launcher.js +1 -0
- package/dist/robopark/vision-agent-launcher.js.map +1 -0
- package/dist/robopark/vision-control.js +1 -0
- package/dist/robopark/vision-control.js.map +1 -0
- package/dist/robopark-cli.js +7 -125
- package/dist/robopark-cli.js.map +1 -0
- package/package.json +16 -25
- package/pi-client/_install_steps.sh +29 -29
- package/pi-client/client.py +76 -76
- package/pi-client/install.sh +40 -40
- package/pi-client/join_convo.sh +54 -54
- package/pi-client/livekit_bridge.py +24 -24
- package/pi-client/motor_bridge.py +10 -10
- package/scheduler/__pycache__/main.cpython-312.pyc +0 -0
- package/scheduler/main.py +196 -17
- package/scheduler/media_lock.py +57 -57
- package/scheduler/preview_agent.py +1122 -1122
- package/scheduler/production_config.json +73 -113
- package/scheduler/scripts/install-robot-supervisor-linux.sh +33 -33
- package/{static → scheduler/static}/vendor/elevenlabs-client.iife.js +24199 -24199
- package/scheduler/static/voice-join.html +177 -0
- package/screen/screen_runtime.py +75 -75
- package/vision/app_pi_clean.py +297 -297
- package/vision/audio_server_pi.py +24 -24
- package/vision/install.sh +34 -34
- package/vision/motor_server.py +275 -275
- package/vision/requirements_camera.txt +6 -6
- package/vision/requirements_motor.txt +4 -4
- package/vision/requirements_pi_unified.txt +2 -2
- package/vision/requirements_vision_agent.txt +19 -19
- package/vision/run.sh +244 -244
- package/vision/services/services.sh +12 -12
- package/dist/kernel/types.js +0 -7
- package/dist/robopark/access.js +0 -99
- package/dist/robopark/control-center-html.js +0 -9191
- package/dist/robopark/control-server.js +0 -148
- package/dist/robopark/deployment-commands.js +0 -47
- package/dist/robopark/standalone.js +0 -562
- package/dist/robopark/voice-join-html.js +0 -57
- package/scripts/windows-shim-fix.cjs +0 -58
- package/static/robopark/barracuda.png +0 -0
- package/static/robopark/bmw.png +0 -0
- package/static/robopark/jaguar.png +0 -0
- package/static/robopark/magnus.jpg +0 -0
- package/static/robopark/panda.png +0 -0
- package/static/robopark/tesla.png +0 -0
- package/static/robopark/titan.jpg +0 -0
- package/static/robopark/volt.png +0 -0
- package/static/vendor/elevenlabs-client.LICENSE +0 -21
|
@@ -1,189 +1,189 @@
|
|
|
1
|
-
"""Durable state for the robot-local voice supervisor.
|
|
2
|
-
|
|
3
|
-
This module deliberately has no scheduler dependency. The voice process writes
|
|
4
|
-
locally first and the management plane may consume events later by cursor.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
import json
|
|
10
|
-
import sqlite3
|
|
11
|
-
import threading
|
|
12
|
-
import time
|
|
13
|
-
import uuid
|
|
14
|
-
from contextlib import contextmanager
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
COMMAND_STATES = {
|
|
19
|
-
"queued", "delivered", "acknowledged", "running", "succeeded",
|
|
20
|
-
"failed", "expired", "superseded",
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class SupervisorStore:
|
|
25
|
-
def __init__(self, config_path: str, robot_id: str, max_events: int = 50_000) -> None:
|
|
26
|
-
source = Path(config_path)
|
|
27
|
-
self.path = source.with_suffix(source.suffix + ".supervisor.sqlite3")
|
|
28
|
-
self.robot_id = robot_id
|
|
29
|
-
self.max_events = max(1_000, int(max_events))
|
|
30
|
-
self.lock = threading.RLock()
|
|
31
|
-
self.path.parent.mkdir(parents=True, exist_ok=True)
|
|
32
|
-
self._initialize()
|
|
33
|
-
|
|
34
|
-
def _connect(self) -> sqlite3.Connection:
|
|
35
|
-
connection = sqlite3.connect(self.path, timeout=10)
|
|
36
|
-
connection.row_factory = sqlite3.Row
|
|
37
|
-
connection.execute("PRAGMA journal_mode=WAL")
|
|
38
|
-
connection.execute("PRAGMA synchronous=NORMAL")
|
|
39
|
-
return connection
|
|
40
|
-
|
|
41
|
-
@contextmanager
|
|
42
|
-
def _db(self):
|
|
43
|
-
connection = self._connect()
|
|
44
|
-
try:
|
|
45
|
-
with connection:
|
|
46
|
-
yield connection
|
|
47
|
-
finally:
|
|
48
|
-
connection.close()
|
|
49
|
-
|
|
50
|
-
def _initialize(self) -> None:
|
|
51
|
-
with self.lock, self._db() as db:
|
|
52
|
-
db.executescript(
|
|
53
|
-
"""
|
|
54
|
-
CREATE TABLE IF NOT EXISTS events (
|
|
55
|
-
sequence INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
56
|
-
event_id TEXT NOT NULL UNIQUE,
|
|
57
|
-
robot_id TEXT NOT NULL,
|
|
58
|
-
session_id TEXT,
|
|
59
|
-
type TEXT NOT NULL,
|
|
60
|
-
timestamp REAL NOT NULL,
|
|
61
|
-
payload TEXT NOT NULL,
|
|
62
|
-
acknowledged INTEGER NOT NULL DEFAULT 0
|
|
63
|
-
);
|
|
64
|
-
CREATE INDEX IF NOT EXISTS idx_voice_events_ack_sequence
|
|
65
|
-
ON events(acknowledged, sequence);
|
|
66
|
-
CREATE TABLE IF NOT EXISTS state (
|
|
67
|
-
key TEXT PRIMARY KEY,
|
|
68
|
-
value TEXT NOT NULL
|
|
69
|
-
);
|
|
70
|
-
CREATE TABLE IF NOT EXISTS completed_commands (
|
|
71
|
-
command_id TEXT PRIMARY KEY,
|
|
72
|
-
status TEXT NOT NULL,
|
|
73
|
-
result TEXT NOT NULL,
|
|
74
|
-
completed_at REAL NOT NULL
|
|
75
|
-
);
|
|
76
|
-
"""
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
def get_state(self, key: str, default=None):
|
|
80
|
-
with self.lock, self._db() as db:
|
|
81
|
-
row = db.execute("SELECT value FROM state WHERE key = ?", (key,)).fetchone()
|
|
82
|
-
return json.loads(row["value"]) if row else default
|
|
83
|
-
|
|
84
|
-
def set_state(self, key: str, value) -> None:
|
|
85
|
-
encoded = json.dumps(value, separators=(",", ":"), ensure_ascii=True)
|
|
86
|
-
with self.lock, self._db() as db:
|
|
87
|
-
db.execute(
|
|
88
|
-
"INSERT INTO state(key, value) VALUES(?, ?) "
|
|
89
|
-
"ON CONFLICT(key) DO UPDATE SET value=excluded.value",
|
|
90
|
-
(key, encoded),
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
def append_event(self, event_type: str, payload: dict, session_id: str | None = None) -> dict:
|
|
94
|
-
event_id = str(uuid.uuid4())
|
|
95
|
-
timestamp = time.time()
|
|
96
|
-
with self.lock, self._db() as db:
|
|
97
|
-
cursor = db.execute(
|
|
98
|
-
"INSERT INTO events(event_id, robot_id, session_id, type, timestamp, payload) "
|
|
99
|
-
"VALUES(?, ?, ?, ?, ?, ?)",
|
|
100
|
-
(
|
|
101
|
-
event_id,
|
|
102
|
-
self.robot_id,
|
|
103
|
-
session_id,
|
|
104
|
-
event_type,
|
|
105
|
-
timestamp,
|
|
106
|
-
json.dumps(payload, separators=(",", ":"), ensure_ascii=True),
|
|
107
|
-
),
|
|
108
|
-
)
|
|
109
|
-
sequence = int(cursor.lastrowid)
|
|
110
|
-
overflow = db.execute(
|
|
111
|
-
"SELECT sequence FROM events ORDER BY sequence DESC LIMIT 1 OFFSET ?",
|
|
112
|
-
(self.max_events,),
|
|
113
|
-
).fetchone()
|
|
114
|
-
if overflow:
|
|
115
|
-
db.execute("DELETE FROM events WHERE sequence <= ? AND acknowledged = 1", (overflow["sequence"],))
|
|
116
|
-
return {
|
|
117
|
-
"event_id": event_id,
|
|
118
|
-
"sequence": sequence,
|
|
119
|
-
"robot_id": self.robot_id,
|
|
120
|
-
"session_id": session_id,
|
|
121
|
-
"type": event_type,
|
|
122
|
-
"timestamp": timestamp,
|
|
123
|
-
"payload": payload,
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
def events_after(self, cursor: int, limit: int = 250) -> list[dict]:
|
|
127
|
-
safe_limit = min(1_000, max(1, int(limit)))
|
|
128
|
-
with self.lock, self._db() as db:
|
|
129
|
-
rows = db.execute(
|
|
130
|
-
"SELECT * FROM events WHERE sequence > ? ORDER BY sequence LIMIT ?",
|
|
131
|
-
(max(0, int(cursor)), safe_limit),
|
|
132
|
-
).fetchall()
|
|
133
|
-
return [
|
|
134
|
-
{
|
|
135
|
-
"event_id": row["event_id"],
|
|
136
|
-
"sequence": row["sequence"],
|
|
137
|
-
"robot_id": row["robot_id"],
|
|
138
|
-
"session_id": row["session_id"],
|
|
139
|
-
"type": row["type"],
|
|
140
|
-
"timestamp": row["timestamp"],
|
|
141
|
-
"payload": json.loads(row["payload"]),
|
|
142
|
-
}
|
|
143
|
-
for row in rows
|
|
144
|
-
]
|
|
145
|
-
|
|
146
|
-
def acknowledge(self, sequence: int) -> int:
|
|
147
|
-
highest = max(0, int(sequence))
|
|
148
|
-
with self.lock, self._db() as db:
|
|
149
|
-
db.execute("UPDATE events SET acknowledged = 1 WHERE sequence <= ?", (highest,))
|
|
150
|
-
db.execute("DELETE FROM events WHERE acknowledged = 1 AND sequence <= ?", (highest,))
|
|
151
|
-
return highest
|
|
152
|
-
|
|
153
|
-
def stats(self) -> dict:
|
|
154
|
-
with self.lock, self._db() as db:
|
|
155
|
-
row = db.execute(
|
|
156
|
-
"SELECT COUNT(*) total, COALESCE(MIN(sequence), 0) first_sequence, "
|
|
157
|
-
"COALESCE(MAX(sequence), 0) last_sequence, "
|
|
158
|
-
"SUM(CASE WHEN acknowledged = 0 THEN 1 ELSE 0 END) pending FROM events"
|
|
159
|
-
).fetchone()
|
|
160
|
-
return {
|
|
161
|
-
"total": int(row["total"] or 0),
|
|
162
|
-
"pending": int(row["pending"] or 0),
|
|
163
|
-
"first_sequence": int(row["first_sequence"] or 0),
|
|
164
|
-
"last_sequence": int(row["last_sequence"] or 0),
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
def command_result(self, command_id: str) -> dict | None:
|
|
168
|
-
with self.lock, self._db() as db:
|
|
169
|
-
row = db.execute(
|
|
170
|
-
"SELECT status, result, completed_at FROM completed_commands WHERE command_id = ?",
|
|
171
|
-
(command_id,),
|
|
172
|
-
).fetchone()
|
|
173
|
-
if not row:
|
|
174
|
-
return None
|
|
175
|
-
return {
|
|
176
|
-
"status": row["status"],
|
|
177
|
-
"result": json.loads(row["result"]),
|
|
178
|
-
"completed_at": row["completed_at"],
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
def complete_command(self, command_id: str, status: str, result: dict) -> None:
|
|
182
|
-
if status not in COMMAND_STATES:
|
|
183
|
-
raise ValueError(f"invalid command state: {status}")
|
|
184
|
-
with self.lock, self._db() as db:
|
|
185
|
-
db.execute(
|
|
186
|
-
"INSERT OR REPLACE INTO completed_commands(command_id, status, result, completed_at) "
|
|
187
|
-
"VALUES(?, ?, ?, ?)",
|
|
188
|
-
(command_id, status, json.dumps(result, ensure_ascii=True), time.time()),
|
|
189
|
-
)
|
|
1
|
+
"""Durable state for the robot-local voice supervisor.
|
|
2
|
+
|
|
3
|
+
This module deliberately has no scheduler dependency. The voice process writes
|
|
4
|
+
locally first and the management plane may consume events later by cursor.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import sqlite3
|
|
11
|
+
import threading
|
|
12
|
+
import time
|
|
13
|
+
import uuid
|
|
14
|
+
from contextlib import contextmanager
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
COMMAND_STATES = {
|
|
19
|
+
"queued", "delivered", "acknowledged", "running", "succeeded",
|
|
20
|
+
"failed", "expired", "superseded",
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SupervisorStore:
|
|
25
|
+
def __init__(self, config_path: str, robot_id: str, max_events: int = 50_000) -> None:
|
|
26
|
+
source = Path(config_path)
|
|
27
|
+
self.path = source.with_suffix(source.suffix + ".supervisor.sqlite3")
|
|
28
|
+
self.robot_id = robot_id
|
|
29
|
+
self.max_events = max(1_000, int(max_events))
|
|
30
|
+
self.lock = threading.RLock()
|
|
31
|
+
self.path.parent.mkdir(parents=True, exist_ok=True)
|
|
32
|
+
self._initialize()
|
|
33
|
+
|
|
34
|
+
def _connect(self) -> sqlite3.Connection:
|
|
35
|
+
connection = sqlite3.connect(self.path, timeout=10)
|
|
36
|
+
connection.row_factory = sqlite3.Row
|
|
37
|
+
connection.execute("PRAGMA journal_mode=WAL")
|
|
38
|
+
connection.execute("PRAGMA synchronous=NORMAL")
|
|
39
|
+
return connection
|
|
40
|
+
|
|
41
|
+
@contextmanager
|
|
42
|
+
def _db(self):
|
|
43
|
+
connection = self._connect()
|
|
44
|
+
try:
|
|
45
|
+
with connection:
|
|
46
|
+
yield connection
|
|
47
|
+
finally:
|
|
48
|
+
connection.close()
|
|
49
|
+
|
|
50
|
+
def _initialize(self) -> None:
|
|
51
|
+
with self.lock, self._db() as db:
|
|
52
|
+
db.executescript(
|
|
53
|
+
"""
|
|
54
|
+
CREATE TABLE IF NOT EXISTS events (
|
|
55
|
+
sequence INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
56
|
+
event_id TEXT NOT NULL UNIQUE,
|
|
57
|
+
robot_id TEXT NOT NULL,
|
|
58
|
+
session_id TEXT,
|
|
59
|
+
type TEXT NOT NULL,
|
|
60
|
+
timestamp REAL NOT NULL,
|
|
61
|
+
payload TEXT NOT NULL,
|
|
62
|
+
acknowledged INTEGER NOT NULL DEFAULT 0
|
|
63
|
+
);
|
|
64
|
+
CREATE INDEX IF NOT EXISTS idx_voice_events_ack_sequence
|
|
65
|
+
ON events(acknowledged, sequence);
|
|
66
|
+
CREATE TABLE IF NOT EXISTS state (
|
|
67
|
+
key TEXT PRIMARY KEY,
|
|
68
|
+
value TEXT NOT NULL
|
|
69
|
+
);
|
|
70
|
+
CREATE TABLE IF NOT EXISTS completed_commands (
|
|
71
|
+
command_id TEXT PRIMARY KEY,
|
|
72
|
+
status TEXT NOT NULL,
|
|
73
|
+
result TEXT NOT NULL,
|
|
74
|
+
completed_at REAL NOT NULL
|
|
75
|
+
);
|
|
76
|
+
"""
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
def get_state(self, key: str, default=None):
|
|
80
|
+
with self.lock, self._db() as db:
|
|
81
|
+
row = db.execute("SELECT value FROM state WHERE key = ?", (key,)).fetchone()
|
|
82
|
+
return json.loads(row["value"]) if row else default
|
|
83
|
+
|
|
84
|
+
def set_state(self, key: str, value) -> None:
|
|
85
|
+
encoded = json.dumps(value, separators=(",", ":"), ensure_ascii=True)
|
|
86
|
+
with self.lock, self._db() as db:
|
|
87
|
+
db.execute(
|
|
88
|
+
"INSERT INTO state(key, value) VALUES(?, ?) "
|
|
89
|
+
"ON CONFLICT(key) DO UPDATE SET value=excluded.value",
|
|
90
|
+
(key, encoded),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
def append_event(self, event_type: str, payload: dict, session_id: str | None = None) -> dict:
|
|
94
|
+
event_id = str(uuid.uuid4())
|
|
95
|
+
timestamp = time.time()
|
|
96
|
+
with self.lock, self._db() as db:
|
|
97
|
+
cursor = db.execute(
|
|
98
|
+
"INSERT INTO events(event_id, robot_id, session_id, type, timestamp, payload) "
|
|
99
|
+
"VALUES(?, ?, ?, ?, ?, ?)",
|
|
100
|
+
(
|
|
101
|
+
event_id,
|
|
102
|
+
self.robot_id,
|
|
103
|
+
session_id,
|
|
104
|
+
event_type,
|
|
105
|
+
timestamp,
|
|
106
|
+
json.dumps(payload, separators=(",", ":"), ensure_ascii=True),
|
|
107
|
+
),
|
|
108
|
+
)
|
|
109
|
+
sequence = int(cursor.lastrowid)
|
|
110
|
+
overflow = db.execute(
|
|
111
|
+
"SELECT sequence FROM events ORDER BY sequence DESC LIMIT 1 OFFSET ?",
|
|
112
|
+
(self.max_events,),
|
|
113
|
+
).fetchone()
|
|
114
|
+
if overflow:
|
|
115
|
+
db.execute("DELETE FROM events WHERE sequence <= ? AND acknowledged = 1", (overflow["sequence"],))
|
|
116
|
+
return {
|
|
117
|
+
"event_id": event_id,
|
|
118
|
+
"sequence": sequence,
|
|
119
|
+
"robot_id": self.robot_id,
|
|
120
|
+
"session_id": session_id,
|
|
121
|
+
"type": event_type,
|
|
122
|
+
"timestamp": timestamp,
|
|
123
|
+
"payload": payload,
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
def events_after(self, cursor: int, limit: int = 250) -> list[dict]:
|
|
127
|
+
safe_limit = min(1_000, max(1, int(limit)))
|
|
128
|
+
with self.lock, self._db() as db:
|
|
129
|
+
rows = db.execute(
|
|
130
|
+
"SELECT * FROM events WHERE sequence > ? ORDER BY sequence LIMIT ?",
|
|
131
|
+
(max(0, int(cursor)), safe_limit),
|
|
132
|
+
).fetchall()
|
|
133
|
+
return [
|
|
134
|
+
{
|
|
135
|
+
"event_id": row["event_id"],
|
|
136
|
+
"sequence": row["sequence"],
|
|
137
|
+
"robot_id": row["robot_id"],
|
|
138
|
+
"session_id": row["session_id"],
|
|
139
|
+
"type": row["type"],
|
|
140
|
+
"timestamp": row["timestamp"],
|
|
141
|
+
"payload": json.loads(row["payload"]),
|
|
142
|
+
}
|
|
143
|
+
for row in rows
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
def acknowledge(self, sequence: int) -> int:
|
|
147
|
+
highest = max(0, int(sequence))
|
|
148
|
+
with self.lock, self._db() as db:
|
|
149
|
+
db.execute("UPDATE events SET acknowledged = 1 WHERE sequence <= ?", (highest,))
|
|
150
|
+
db.execute("DELETE FROM events WHERE acknowledged = 1 AND sequence <= ?", (highest,))
|
|
151
|
+
return highest
|
|
152
|
+
|
|
153
|
+
def stats(self) -> dict:
|
|
154
|
+
with self.lock, self._db() as db:
|
|
155
|
+
row = db.execute(
|
|
156
|
+
"SELECT COUNT(*) total, COALESCE(MIN(sequence), 0) first_sequence, "
|
|
157
|
+
"COALESCE(MAX(sequence), 0) last_sequence, "
|
|
158
|
+
"SUM(CASE WHEN acknowledged = 0 THEN 1 ELSE 0 END) pending FROM events"
|
|
159
|
+
).fetchone()
|
|
160
|
+
return {
|
|
161
|
+
"total": int(row["total"] or 0),
|
|
162
|
+
"pending": int(row["pending"] or 0),
|
|
163
|
+
"first_sequence": int(row["first_sequence"] or 0),
|
|
164
|
+
"last_sequence": int(row["last_sequence"] or 0),
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
def command_result(self, command_id: str) -> dict | None:
|
|
168
|
+
with self.lock, self._db() as db:
|
|
169
|
+
row = db.execute(
|
|
170
|
+
"SELECT status, result, completed_at FROM completed_commands WHERE command_id = ?",
|
|
171
|
+
(command_id,),
|
|
172
|
+
).fetchone()
|
|
173
|
+
if not row:
|
|
174
|
+
return None
|
|
175
|
+
return {
|
|
176
|
+
"status": row["status"],
|
|
177
|
+
"result": json.loads(row["result"]),
|
|
178
|
+
"completed_at": row["completed_at"],
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
def complete_command(self, command_id: str, status: str, result: dict) -> None:
|
|
182
|
+
if status not in COMMAND_STATES:
|
|
183
|
+
raise ValueError(f"invalid command state: {status}")
|
|
184
|
+
with self.lock, self._db() as db:
|
|
185
|
+
db.execute(
|
|
186
|
+
"INSERT OR REPLACE INTO completed_commands(command_id, status, result, completed_at) "
|
|
187
|
+
"VALUES(?, ?, ?, ?)",
|
|
188
|
+
(command_id, status, json.dumps(result, ensure_ascii=True), time.time()),
|
|
189
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-schema.js","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"AAgGA,MAAM,CAAC,MAAM,cAAc,GAAqB;IAC9C,SAAS,EAAE,wBAAwB;IACnC,YAAY,EAAE,mBAAmB;IACjC,KAAK,EAAE,QAAQ;IACf,4EAA4E;IAC5E,4EAA4E;IAC5E,MAAM,EAAE,UAAU;IAClB,YAAY,EAAE,EAAE;IAChB,cAAc,EAAE,EAAE;IAClB,cAAc,EAAE,EAAE;CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAiB;IAC9C,QAAQ;IACR,UAAU;IACV,UAAU;IACV,cAAc;IACd,QAAQ;IACR,eAAe;IACf,aAAa;IACb,UAAU;IACV,cAAc;IACd,QAAQ;IACR,SAAS;CACV,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAA+B;IAC7D,MAAM,EAAE,iDAAiD;IACzD,QAAQ,EAAE,0FAA0F;IACpG,QAAQ,EAAE,6CAA6C;IACvD,YAAY,EAAE,kDAAkD;IAChE,MAAM,EAAE,kCAAkC;IAC1C,aAAa,EAAE,2BAA2B;IAC1C,WAAW,EAAE,qCAAqC;IAClD,QAAQ,EAAE,yBAAyB;IACnC,YAAY,EAAE,yCAAyC;IACvD,MAAM,EAAE,sCAAsC;IAC9C,OAAO,EAAE,iCAAiC;CAC3C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-robot.js","sourceRoot":"","sources":["../../src/robopark/add-robot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-ctl.js","sourceRoot":"","sources":["../../src/robopark/agent-ctl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,YAAY,GAAG,IAAI,CAAC;AAC1B,MAAM,mBAAmB,GAAG,QAAQ,CAAC;AACrC,MAAM,sBAAsB,GAAG,QAAQ,CAAC;AAsBxC,kEAAkE;AAClE,SAAS,SAAS;IAChB,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,QAAQ;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6DAA6D;AAC7D,SAAS,YAAY,CAAC,GAAW,EAAE,IAAc;IAC/C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,qBAAqB;IAClC,IAAI,MAAM,YAAY,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QACzD,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;IAClD,CAAC;IACD,IAAI,MAAM,YAAY,CAAC,gBAAgB,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,0EAA0E;AAC1E,SAAS,UAAU,CAAC,OAA4C,EAAE,IAAc,EAAE,GAAW;IAC3F,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,EAAE;YAC9D,GAAG;YACH,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,qJAAqJ;AACrJ,KAAK,UAAU,qBAAqB,CAAC,IAAY,EAAE,SAAiB,EAAE,UAAkB;IACtF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACxC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5F,2EAA2E;YAC3E,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG;gBAAE,OAAO,IAAI,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,qCAAqC;QACvC,CAAC;QACD,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,wFAAwF;AACxF,SAAS,mBAAmB,CAAC,IAAY;IACvC,MAAM,UAAU,GAAG,CAAC,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;IACjE,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9B,IAAI,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IACpC,CAAC;IACD,MAAM,IAAI,KAAK,CACb,yCAAyC,IAAI,kDAAkD;QAC/F,gEAAgE,CACjE,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,SAAS,+BAA+B,CAAC,IAAY;IACnD,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC;QAC5B,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,gBAAgB,CAAC;QACnC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,gBAAgB,CAAC;KACpC,CAAC;IACF,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IACnE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,8EAA8E,EAAE,CAAC;IACrH,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1C,IAAI,OAAO,GAAG,MAAM,CAAC;IACrB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACxD,MAAM,iBAAiB,GAAG,6DAA6D,CAAC;IACxF,MAAM,WAAW,GAAG,6CAA6C,CAAC;IAClE,MAAM,SAAS,GAAG,gCAAgC,CAAC;IACnD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChE,IAAI,KAAK,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,IAAI;gBACJ,OAAO,EAAE,sGAAsG;aAChH,CAAC;QACJ,CAAC;QACD,MAAM,WAAW,GAAG;YAClB,yEAAyE;YACzE,0EAA0E;YAC1E,wCAAwC;YACxC,uEAAuE;YACvE,8CAA8C;YAC9C,8BAA8B;YAC9B,uDAAuD;YACvD,iDAAiD;YACjD,wFAAwF;YACxF,EAAE;SACH,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChB,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrE,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,2EAA2E;IAC3E,0EAA0E;IAC1E,MAAM,UAAU,GAAG,4FAA4F,CAAC;IAChH,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE;YACpC,6EAA6E;YAC7E,oFAAoF;YACpF,oCAAoC;SACrC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACjB,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,IAAI,OAAO;QAAE,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAClD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAoB;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAE9C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC;QACH,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAQ,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mFAAmF,CAAC,CAAC,CAAC;QAC5G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC1F,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,MAAM,aAAa,GAAG,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,mDAAmD,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACpG,CAAC;SAAM,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC,CAAC;IACxF,yEAAyE;IACzE,wDAAwD;IACxD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,+CAA+C,MAAM,EAAE,CAAC,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;IAE/D,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kDAAkD,YAAY,eAAe,CAAC,CAAC,CAAC;IACvG,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IACzE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mDAAmD,YAAY,cAAc,CAAC,CAAC,CAAC;QACtG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,+BAA+B,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,YAAY,EAAE,CAAC,CAAC,CAAC;IAElE,IAAI,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC,CAAC;QACnF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC,CAAC;QAC7E,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC,CAAC;IAExF,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;IAC9G,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0GAA0G,CAAC,CAAC,CAAC;QACnI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,wEAAwE;IACxE,kEAAkE;IAClE,uEAAuE;IACvE,0EAA0E;IAC1E,2FAA2F;IAC3F,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC;IAC9C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,mDAAmD,aAAa,0EAA0E,CAAC,CAAC,CAAC;IACxK,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,IAAI,aAAa,QAAQ,EAAE,EAAE,CAAC;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,cAAc,QAAQ,EAAE,GAAG,CAAC;IAC5D,MAAM,GAAG,GAAG,QAAQ,aAAa,IAAI,YAAY,EAAE,CAAC;IAEpD,MAAM,iBAAiB,CAAC;QACtB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,EAAE;QACF,IAAI;QACJ,GAAG;QACH,MAAM,EAAE,mBAAmB;QAC3B,SAAS,EAAE,sBAAsB;KAClC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,6FAA6F,CAAC,CAAC,CAAC;AAC1H,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAsB;IAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAE9C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC;QACH,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAQ,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mFAAmF,CAAC,CAAC,CAAC;QAC5G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8CAA8C,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAsB;IAC5D,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC;QACH,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAQ,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mFAAmF,CAAC,CAAC,CAAC;QAC5G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,IAAI,IAAI,CAAC,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,IAAI,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAE1C,gEAAgE;IAChE,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;AACH,CAAC"}
|
|
@@ -33,20 +33,14 @@ async function registerWindows(service) {
|
|
|
33
33
|
mkdirSync(logDir, { recursive: true });
|
|
34
34
|
const outLog = join(logDir, `${taskName}.log`);
|
|
35
35
|
const errLog = join(logDir, `${taskName}.err.log`);
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const cmd = ['powershell.exe', '-WindowStyle', 'Hidden', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-Command', script];
|
|
36
|
+
const script = [service.command, ...service.args].map(shellQuote).join(' ');
|
|
37
|
+
const cmd = ['powershell.exe', '-WindowStyle', 'Hidden', '-ExecutionPolicy', 'Bypass', '-Command', script];
|
|
39
38
|
const xmlPath = join(homedir(), 'AppData', 'Roaming', 'robopark', `${taskName}.xml`);
|
|
40
39
|
mkdirSync(dirname(xmlPath), { recursive: true });
|
|
41
40
|
const xml = `<?xml version="1.0" encoding="UTF-16"?>\n<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">\n <RegistrationInfo>\n <Description>RoboPark ${service.role} for ${service.name}</Description>\n </RegistrationInfo>\n <Triggers>\n <BootTrigger>\n <Enabled>true</Enabled>\n </BootTrigger>\n <LogonTrigger>\n <Enabled>true</Enabled>\n </LogonTrigger>\n </Triggers>\n <Principals>\n <Principal id="Author">\n <LogonType>S4U</LogonType>\n <RunLevel>HighestAvailable</RunLevel>\n </Principal>\n </Principals>\n <Settings>\n <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>\n <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>\n <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>\n <StartWhenAvailable>true</StartWhenAvailable>\n <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>\n <IdleSettings>\n <StopOnIdleEnd>false</StopOnIdleEnd>\n <RestartOnIdle>false</RestartOnIdle>\n </IdleSettings>\n <AllowStartOnDemand>true</AllowStartOnDemand>\n <Enabled>true</Enabled>\n <Hidden>false</Hidden>\n <RunOnlyIfIdle>false</RunOnlyIfIdle>\n <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>\n <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>\n <WakeToRun>false</WakeToRun>\n <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>\n </Settings>\n <Actions Context="Author">\n <Exec>\n <Command>${cmd[0]}</Command>\n <Arguments>${cmd.slice(1).map(a => a.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>')).join(' ')}</Arguments>\n <WorkingDirectory>${service.workingDir ?? homedir()}</WorkingDirectory>\n </Exec>\n </Actions>\n</Task>`;
|
|
42
|
-
const hardenedXml = xml.replace(' </Settings>',
|
|
43
|
-
// Task Scheduler rejects restart intervals shorter than one minute with
|
|
44
|
-
// ERROR_INVALID_DATA. The RoboPark child supervisor handles sub-minute
|
|
45
|
-
// recovery; Windows is the outer process-level safety net.
|
|
46
|
-
' <RestartOnFailure>\n <Interval>PT1M</Interval>\n <Count>999</Count>\n </RestartOnFailure>\n </Settings>');
|
|
47
41
|
// schtasks /XML requires UTF-16 LE *with* BOM when the XML declares UTF-16.
|
|
48
42
|
const bom = Buffer.from([0xff, 0xfe]);
|
|
49
|
-
const body = Buffer.from(
|
|
43
|
+
const body = Buffer.from(xml, 'utf16le');
|
|
50
44
|
writeFileSync(xmlPath, Buffer.concat([bom, body]));
|
|
51
45
|
return new Promise((resolve) => {
|
|
52
46
|
const schtasks = spawn('schtasks', ['/Create', '/TN', taskName, '/XML', xmlPath, '/F'], { stdio: 'pipe' });
|
|
@@ -56,13 +50,7 @@ async function registerWindows(service) {
|
|
|
56
50
|
schtasks.stderr.on('data', d => (err += d.toString()));
|
|
57
51
|
schtasks.on('close', code => {
|
|
58
52
|
if (code === 0) {
|
|
59
|
-
|
|
60
|
-
if (started.status === 0) {
|
|
61
|
-
resolve({ ok: true, message: `registered and started Windows Task Scheduler task "${taskName}"` });
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
resolve({ ok: false, message: `registered "${taskName}", but could not start it: ${started.stderr || started.stdout}` });
|
|
65
|
-
}
|
|
53
|
+
resolve({ ok: true, message: `registered Windows Task Scheduler task "${taskName}"` });
|
|
66
54
|
}
|
|
67
55
|
else {
|
|
68
56
|
resolve({ ok: false, message: `schtasks failed (${code}): ${err || out}` });
|
|
@@ -122,29 +110,29 @@ async function registerSystemd(service) {
|
|
|
122
110
|
// The explicit systemd groups below still cover standard distro rules.
|
|
123
111
|
}
|
|
124
112
|
}
|
|
125
|
-
const unit = `[Unit]
|
|
126
|
-
Description=RoboPark ${service.role} for ${service.name}
|
|
127
|
-
After=network-online.target sound.target
|
|
128
|
-
Wants=network-online.target sound.target
|
|
129
|
-
${startLimit}
|
|
130
|
-
|
|
131
|
-
[Service]
|
|
132
|
-
Type=simple
|
|
133
|
-
${exclusiveMediaPreflight}
|
|
134
|
-
${motorPreflight}
|
|
135
|
-
ExecStart=${service.command} ${service.args.map(shellQuote).join(' ')}
|
|
136
|
-
WorkingDirectory=${service.workingDir ?? homedir()}
|
|
137
|
-
Restart=always
|
|
138
|
-
RestartSec=${restartSeconds}
|
|
139
|
-
KillMode=control-group
|
|
140
|
-
TimeoutStopSec=20
|
|
141
|
-
SendSIGKILL=yes
|
|
142
|
-
FinalKillSignal=SIGKILL
|
|
143
|
-
${mediaPolicy}
|
|
144
|
-
${envLines}
|
|
145
|
-
|
|
146
|
-
[Install]
|
|
147
|
-
WantedBy=multi-user.target
|
|
113
|
+
const unit = `[Unit]
|
|
114
|
+
Description=RoboPark ${service.role} for ${service.name}
|
|
115
|
+
After=network-online.target sound.target
|
|
116
|
+
Wants=network-online.target sound.target
|
|
117
|
+
${startLimit}
|
|
118
|
+
|
|
119
|
+
[Service]
|
|
120
|
+
Type=simple
|
|
121
|
+
${exclusiveMediaPreflight}
|
|
122
|
+
${motorPreflight}
|
|
123
|
+
ExecStart=${service.command} ${service.args.map(shellQuote).join(' ')}
|
|
124
|
+
WorkingDirectory=${service.workingDir ?? homedir()}
|
|
125
|
+
Restart=always
|
|
126
|
+
RestartSec=${restartSeconds}
|
|
127
|
+
KillMode=control-group
|
|
128
|
+
TimeoutStopSec=20
|
|
129
|
+
SendSIGKILL=yes
|
|
130
|
+
FinalKillSignal=SIGKILL
|
|
131
|
+
${mediaPolicy}
|
|
132
|
+
${envLines}
|
|
133
|
+
|
|
134
|
+
[Install]
|
|
135
|
+
WantedBy=multi-user.target
|
|
148
136
|
`;
|
|
149
137
|
try {
|
|
150
138
|
writeFileSync(unitPath, unit, 'utf8');
|
|
@@ -208,44 +196,33 @@ async function registerLaunchd(service) {
|
|
|
208
196
|
const plistPath = join(homedir(), 'Library', 'LaunchAgents', `${label}.plist`);
|
|
209
197
|
mkdirSync(join(homedir(), 'Library', 'LaunchAgents'), { recursive: true });
|
|
210
198
|
const env = service.env ?? {};
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
</
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
<
|
|
223
|
-
<
|
|
224
|
-
<
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
<key>
|
|
229
|
-
<string>${
|
|
230
|
-
<key>
|
|
231
|
-
<
|
|
232
|
-
|
|
233
|
-
<true/>
|
|
234
|
-
<key>StandardOutPath</key>
|
|
235
|
-
<string>${join(homedir(), 'Library', 'Logs', `${label}.log`)}</string>
|
|
236
|
-
<key>StandardErrorPath</key>
|
|
237
|
-
<string>${join(homedir(), 'Library', 'Logs', `${label}.err.log`)}</string>
|
|
238
|
-
${envBlock}
|
|
199
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
200
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
201
|
+
<plist version="1.0">
|
|
202
|
+
<dict>
|
|
203
|
+
<key>Label</key>
|
|
204
|
+
<string>${label}</string>
|
|
205
|
+
<key>ProgramArguments</key>
|
|
206
|
+
<array>
|
|
207
|
+
<string>${service.command}</string>
|
|
208
|
+
${service.args.map(a => `<string>${a.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"')}</string>`).join('\n ')}
|
|
209
|
+
</array>
|
|
210
|
+
<key>WorkingDirectory</key>
|
|
211
|
+
<string>${service.workingDir ?? homedir()}</string>
|
|
212
|
+
<key>RunAtLoad</key>
|
|
213
|
+
<true/>
|
|
214
|
+
<key>KeepAlive</key>
|
|
215
|
+
<true/>
|
|
216
|
+
<key>StandardOutPath</key>
|
|
217
|
+
<string>${join(homedir(), 'Library', 'Logs', `${label}.log`)}</string>
|
|
218
|
+
<key>StandardErrorPath</key>
|
|
219
|
+
<string>${join(homedir(), 'Library', 'Logs', `${label}.err.log`)}</string>
|
|
220
|
+
${Object.entries(env).map(([k, v]) => `<key>EnvironmentVariables</key>\n <dict>\n <key>${k}</key>\n <string>${v}</string>\n </dict>`).join('\n ')}
|
|
239
221
|
</dict>
|
|
240
222
|
</plist>`;
|
|
241
223
|
try {
|
|
242
224
|
writeFileSync(plistPath, plist, 'utf8');
|
|
243
|
-
|
|
244
|
-
const loaded = spawnSync('launchctl', ['load', '-w', plistPath], { encoding: 'utf8' });
|
|
245
|
-
if (loaded.status !== 0) {
|
|
246
|
-
return { ok: false, message: `wrote ${plistPath}, but launchctl failed: ${loaded.stderr || loaded.stdout}` };
|
|
247
|
-
}
|
|
248
|
-
return { ok: true, message: `registered and started launchd service ${label}` };
|
|
225
|
+
return { ok: true, message: `wrote launchd plist ${plistPath}. Run: launchctl load ${plistPath}` };
|
|
249
226
|
}
|
|
250
227
|
catch (e) {
|
|
251
228
|
return { ok: false, message: `could not write ${plistPath}: ${e instanceof Error ? e.message : String(e)}` };
|
|
@@ -291,3 +268,4 @@ export function unregisterAutoStart(role, name) {
|
|
|
291
268
|
}
|
|
292
269
|
return { ok: false, message: `unregister not supported on ${platform}` };
|
|
293
270
|
}
|
|
271
|
+
//# sourceMappingURL=auto-start.js.map
|