arkaos 2.9.0 → 2.10.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/VERSION +1 -1
- package/config/cognition/prompts/dreaming.md +208 -0
- package/config/cognition/prompts/research.md +194 -0
- package/config/cognition/schedules.yaml +25 -0
- package/core/cognition/__init__.py +7 -0
- package/core/cognition/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/cognition/capture/__init__.py +5 -0
- package/core/cognition/capture/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/cognition/capture/__pycache__/collector.cpython-313.pyc +0 -0
- package/core/cognition/capture/__pycache__/store.cpython-313.pyc +0 -0
- package/core/cognition/capture/collector.py +80 -0
- package/core/cognition/capture/store.py +158 -0
- package/core/cognition/insights/__init__.py +5 -0
- package/core/cognition/insights/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/cognition/insights/__pycache__/store.cpython-313.pyc +0 -0
- package/core/cognition/insights/store.py +155 -0
- package/core/cognition/memory/__init__.py +9 -0
- package/core/cognition/memory/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/cognition/memory/__pycache__/obsidian.cpython-313.pyc +0 -0
- package/core/cognition/memory/__pycache__/schemas.cpython-313.pyc +0 -0
- package/core/cognition/memory/__pycache__/vector.cpython-313.pyc +0 -0
- package/core/cognition/memory/__pycache__/writer.cpython-313.pyc +0 -0
- package/core/cognition/memory/obsidian.py +73 -0
- package/core/cognition/memory/schemas.py +141 -0
- package/core/cognition/memory/vector.py +223 -0
- package/core/cognition/memory/writer.py +57 -0
- package/core/cognition/research/__init__.py +5 -0
- package/core/cognition/research/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/cognition/research/__pycache__/profiler.cpython-313.pyc +0 -0
- package/core/cognition/research/profiler.py +256 -0
- package/core/cognition/scheduler/__init__.py +5 -0
- package/core/cognition/scheduler/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/cognition/scheduler/__pycache__/cli.cpython-313.pyc +0 -0
- package/core/cognition/scheduler/__pycache__/daemon.cpython-313.pyc +0 -0
- package/core/cognition/scheduler/__pycache__/platform.cpython-313.pyc +0 -0
- package/core/cognition/scheduler/cli.py +86 -0
- package/core/cognition/scheduler/daemon.py +172 -0
- package/core/cognition/scheduler/platform.py +292 -0
- package/package.json +1 -1
- package/pyproject.toml +1 -1
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"""Cross-platform service adapters for the ArkaOS cognitive scheduler.
|
|
2
|
+
|
|
3
|
+
Supports macOS (launchd), Linux (systemd), and Windows (schtasks).
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import shutil
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
from abc import ABC, abstractmethod
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _default_daemon_script() -> str:
|
|
14
|
+
return str(Path.home() / ".arkaos" / "bin" / "scheduler-daemon.py")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _python_executable() -> str:
|
|
18
|
+
return shutil.which("python3") or sys.executable
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PlatformAdapter(ABC):
|
|
22
|
+
"""Abstract base for OS-level service management."""
|
|
23
|
+
|
|
24
|
+
platform_name: str
|
|
25
|
+
|
|
26
|
+
@abstractmethod
|
|
27
|
+
def install_service(self) -> bool: ...
|
|
28
|
+
|
|
29
|
+
@abstractmethod
|
|
30
|
+
def uninstall_service(self) -> bool: ...
|
|
31
|
+
|
|
32
|
+
@abstractmethod
|
|
33
|
+
def is_running(self) -> bool: ...
|
|
34
|
+
|
|
35
|
+
@abstractmethod
|
|
36
|
+
def start(self) -> bool: ...
|
|
37
|
+
|
|
38
|
+
@abstractmethod
|
|
39
|
+
def stop(self) -> bool: ...
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class MacOSAdapter(PlatformAdapter):
|
|
43
|
+
"""launchd adapter for macOS."""
|
|
44
|
+
|
|
45
|
+
platform_name = "macos"
|
|
46
|
+
|
|
47
|
+
_LABEL = "com.arkaos.scheduler"
|
|
48
|
+
|
|
49
|
+
def __init__(self, daemon_script: str, plist_dir: str | None = None) -> None:
|
|
50
|
+
self._daemon_script = daemon_script
|
|
51
|
+
self._plist_dir = plist_dir or str(
|
|
52
|
+
Path.home() / "Library" / "LaunchAgents"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def _plist_path(self) -> str:
|
|
56
|
+
return str(Path(self._plist_dir) / f"{self._LABEL}.plist")
|
|
57
|
+
|
|
58
|
+
def _generate_plist(self) -> str:
|
|
59
|
+
python = _python_executable()
|
|
60
|
+
log_dir = Path.home() / ".arkaos" / "logs"
|
|
61
|
+
stdout = str(log_dir / "scheduler-stdout.log")
|
|
62
|
+
stderr = str(log_dir / "scheduler-stderr.log")
|
|
63
|
+
return (
|
|
64
|
+
'<?xml version="1.0" encoding="UTF-8"?>\n'
|
|
65
|
+
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"'
|
|
66
|
+
' "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n'
|
|
67
|
+
'<plist version="1.0">\n'
|
|
68
|
+
"<dict>\n"
|
|
69
|
+
f"\t<key>Label</key>\n\t<string>{self._LABEL}</string>\n"
|
|
70
|
+
f"\t<key>ProgramArguments</key>\n"
|
|
71
|
+
f"\t<array>\n\t\t<string>{python}</string>"
|
|
72
|
+
f"\n\t\t<string>{self._daemon_script}</string>\n\t</array>\n"
|
|
73
|
+
"\t<key>RunAtLoad</key>\n\t<true/>\n"
|
|
74
|
+
"\t<key>KeepAlive</key>\n\t<true/>\n"
|
|
75
|
+
f"\t<key>StandardOutPath</key>\n\t<string>{stdout}</string>\n"
|
|
76
|
+
f"\t<key>StandardErrorPath</key>\n\t<string>{stderr}</string>\n"
|
|
77
|
+
"</dict>\n"
|
|
78
|
+
"</plist>\n"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
def install_service(self) -> bool:
|
|
82
|
+
"""Write plist and load it via launchctl."""
|
|
83
|
+
plist = Path(self._plist_path())
|
|
84
|
+
plist.parent.mkdir(parents=True, exist_ok=True)
|
|
85
|
+
plist.write_text(self._generate_plist(), encoding="utf-8")
|
|
86
|
+
return self.start()
|
|
87
|
+
|
|
88
|
+
def uninstall_service(self) -> bool:
|
|
89
|
+
"""Unload and remove the plist."""
|
|
90
|
+
self.stop()
|
|
91
|
+
plist = Path(self._plist_path())
|
|
92
|
+
if plist.exists():
|
|
93
|
+
plist.unlink()
|
|
94
|
+
return True
|
|
95
|
+
|
|
96
|
+
def is_running(self) -> bool:
|
|
97
|
+
"""Return True when launchctl reports the service as running."""
|
|
98
|
+
try:
|
|
99
|
+
result = subprocess.run(
|
|
100
|
+
["launchctl", "list", self._LABEL],
|
|
101
|
+
capture_output=True,
|
|
102
|
+
text=True,
|
|
103
|
+
)
|
|
104
|
+
return result.returncode == 0
|
|
105
|
+
except Exception: # noqa: BLE001
|
|
106
|
+
return False
|
|
107
|
+
|
|
108
|
+
def start(self) -> bool:
|
|
109
|
+
try:
|
|
110
|
+
result = subprocess.run(
|
|
111
|
+
["launchctl", "load", self._plist_path()],
|
|
112
|
+
capture_output=True,
|
|
113
|
+
)
|
|
114
|
+
return result.returncode == 0
|
|
115
|
+
except Exception: # noqa: BLE001
|
|
116
|
+
return False
|
|
117
|
+
|
|
118
|
+
def stop(self) -> bool:
|
|
119
|
+
try:
|
|
120
|
+
result = subprocess.run(
|
|
121
|
+
["launchctl", "unload", self._plist_path()],
|
|
122
|
+
capture_output=True,
|
|
123
|
+
)
|
|
124
|
+
return result.returncode == 0
|
|
125
|
+
except Exception: # noqa: BLE001
|
|
126
|
+
return False
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class LinuxAdapter(PlatformAdapter):
|
|
130
|
+
"""systemd --user adapter for Linux."""
|
|
131
|
+
|
|
132
|
+
platform_name = "linux"
|
|
133
|
+
|
|
134
|
+
_SERVICE_NAME = "arkaos-scheduler.service"
|
|
135
|
+
|
|
136
|
+
def __init__(self, daemon_script: str, service_dir: str | None = None) -> None:
|
|
137
|
+
self._daemon_script = daemon_script
|
|
138
|
+
self._service_dir = service_dir or str(
|
|
139
|
+
Path.home() / ".config" / "systemd" / "user"
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
def _service_path(self) -> str:
|
|
143
|
+
return str(Path(self._service_dir) / self._SERVICE_NAME)
|
|
144
|
+
|
|
145
|
+
def _generate_unit(self) -> str:
|
|
146
|
+
python = _python_executable()
|
|
147
|
+
return (
|
|
148
|
+
"[Unit]\n"
|
|
149
|
+
"Description=ArkaOS Cognitive Scheduler\n"
|
|
150
|
+
"After=network.target\n\n"
|
|
151
|
+
"[Service]\n"
|
|
152
|
+
"Type=simple\n"
|
|
153
|
+
f"ExecStart={python} {self._daemon_script}\n"
|
|
154
|
+
"Restart=on-failure\n"
|
|
155
|
+
"RestartSec=60\n\n"
|
|
156
|
+
"[Install]\n"
|
|
157
|
+
"WantedBy=default.target\n"
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
def install_service(self) -> bool:
|
|
161
|
+
"""Write unit file and enable it via systemctl --user."""
|
|
162
|
+
service = Path(self._service_path())
|
|
163
|
+
service.parent.mkdir(parents=True, exist_ok=True)
|
|
164
|
+
service.write_text(self._generate_unit(), encoding="utf-8")
|
|
165
|
+
return self.start()
|
|
166
|
+
|
|
167
|
+
def uninstall_service(self) -> bool:
|
|
168
|
+
"""Disable and remove the unit file."""
|
|
169
|
+
self.stop()
|
|
170
|
+
service = Path(self._service_path())
|
|
171
|
+
if service.exists():
|
|
172
|
+
service.unlink()
|
|
173
|
+
return True
|
|
174
|
+
|
|
175
|
+
def is_running(self) -> bool:
|
|
176
|
+
try:
|
|
177
|
+
result = subprocess.run(
|
|
178
|
+
["systemctl", "--user", "is-active", self._SERVICE_NAME],
|
|
179
|
+
capture_output=True,
|
|
180
|
+
text=True,
|
|
181
|
+
)
|
|
182
|
+
return result.stdout.strip() == "active"
|
|
183
|
+
except Exception: # noqa: BLE001
|
|
184
|
+
return False
|
|
185
|
+
|
|
186
|
+
def start(self) -> bool:
|
|
187
|
+
try:
|
|
188
|
+
result = subprocess.run(
|
|
189
|
+
["systemctl", "--user", "enable", "--now", self._SERVICE_NAME],
|
|
190
|
+
capture_output=True,
|
|
191
|
+
)
|
|
192
|
+
return result.returncode == 0
|
|
193
|
+
except Exception: # noqa: BLE001
|
|
194
|
+
return False
|
|
195
|
+
|
|
196
|
+
def stop(self) -> bool:
|
|
197
|
+
try:
|
|
198
|
+
result = subprocess.run(
|
|
199
|
+
["systemctl", "--user", "disable", "--now", self._SERVICE_NAME],
|
|
200
|
+
capture_output=True,
|
|
201
|
+
)
|
|
202
|
+
return result.returncode == 0
|
|
203
|
+
except Exception: # noqa: BLE001
|
|
204
|
+
return False
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class WindowsAdapter(PlatformAdapter):
|
|
208
|
+
"""schtasks adapter for Windows."""
|
|
209
|
+
|
|
210
|
+
platform_name = "windows"
|
|
211
|
+
|
|
212
|
+
_TASK_NAME = "ArkaOS-Scheduler"
|
|
213
|
+
|
|
214
|
+
def __init__(self, daemon_script: str) -> None:
|
|
215
|
+
self._daemon_script = daemon_script
|
|
216
|
+
|
|
217
|
+
def _build_schtasks_command(self) -> list[str]:
|
|
218
|
+
python = _python_executable()
|
|
219
|
+
return [
|
|
220
|
+
"schtasks",
|
|
221
|
+
"/Create",
|
|
222
|
+
"/F",
|
|
223
|
+
"/TN",
|
|
224
|
+
self._TASK_NAME,
|
|
225
|
+
"/SC",
|
|
226
|
+
"ONLOGON",
|
|
227
|
+
"/TR",
|
|
228
|
+
f"{python} {self._daemon_script}",
|
|
229
|
+
]
|
|
230
|
+
|
|
231
|
+
def install_service(self) -> bool:
|
|
232
|
+
try:
|
|
233
|
+
result = subprocess.run(
|
|
234
|
+
self._build_schtasks_command(),
|
|
235
|
+
capture_output=True,
|
|
236
|
+
)
|
|
237
|
+
return result.returncode == 0
|
|
238
|
+
except Exception: # noqa: BLE001
|
|
239
|
+
return False
|
|
240
|
+
|
|
241
|
+
def uninstall_service(self) -> bool:
|
|
242
|
+
try:
|
|
243
|
+
result = subprocess.run(
|
|
244
|
+
["schtasks", "/Delete", "/F", "/TN", self._TASK_NAME],
|
|
245
|
+
capture_output=True,
|
|
246
|
+
)
|
|
247
|
+
return result.returncode == 0
|
|
248
|
+
except Exception: # noqa: BLE001
|
|
249
|
+
return False
|
|
250
|
+
|
|
251
|
+
def is_running(self) -> bool:
|
|
252
|
+
try:
|
|
253
|
+
result = subprocess.run(
|
|
254
|
+
["schtasks", "/Query", "/TN", self._TASK_NAME, "/FO", "LIST"],
|
|
255
|
+
capture_output=True,
|
|
256
|
+
text=True,
|
|
257
|
+
)
|
|
258
|
+
return result.returncode == 0 and "Running" in result.stdout
|
|
259
|
+
except Exception: # noqa: BLE001
|
|
260
|
+
return False
|
|
261
|
+
|
|
262
|
+
def start(self) -> bool:
|
|
263
|
+
try:
|
|
264
|
+
result = subprocess.run(
|
|
265
|
+
["schtasks", "/Run", "/TN", self._TASK_NAME],
|
|
266
|
+
capture_output=True,
|
|
267
|
+
)
|
|
268
|
+
return result.returncode == 0
|
|
269
|
+
except Exception: # noqa: BLE001
|
|
270
|
+
return False
|
|
271
|
+
|
|
272
|
+
def stop(self) -> bool:
|
|
273
|
+
try:
|
|
274
|
+
result = subprocess.run(
|
|
275
|
+
["schtasks", "/End", "/TN", self._TASK_NAME],
|
|
276
|
+
capture_output=True,
|
|
277
|
+
)
|
|
278
|
+
return result.returncode == 0
|
|
279
|
+
except Exception: # noqa: BLE001
|
|
280
|
+
return False
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def detect_platform() -> PlatformAdapter:
|
|
284
|
+
"""Return the correct adapter for the current operating system."""
|
|
285
|
+
daemon_script = _default_daemon_script()
|
|
286
|
+
if sys.platform == "darwin":
|
|
287
|
+
return MacOSAdapter(daemon_script=daemon_script)
|
|
288
|
+
if sys.platform.startswith("linux"):
|
|
289
|
+
return LinuxAdapter(daemon_script=daemon_script)
|
|
290
|
+
if sys.platform == "win32":
|
|
291
|
+
return WindowsAdapter(daemon_script=daemon_script)
|
|
292
|
+
raise RuntimeError(f"Unsupported platform: {sys.platform}")
|
package/package.json
CHANGED