arkaos 3.70.9 → 3.71.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/core/personas/__pycache__/obsidian_store.cpython-313.pyc +0 -0
- package/core/personas/obsidian_store.py +7 -0
- package/core/terminal/__pycache__/session.cpython-313.pyc +0 -0
- package/core/terminal/session.py +28 -0
- package/dashboard/app/components/TerminalDock.vue +638 -0
- package/dashboard/app/composables/useTerminalDock.ts +88 -0
- package/dashboard/app/composables/useTerminalSession.ts +68 -29
- package/dashboard/app/composables/useTerminalTabs.ts +121 -46
- package/dashboard/app/layouts/default.vue +6 -0
- package/dashboard/app/pages/terminal.vue +25 -531
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/scripts/__pycache__/dashboard-api.cpython-313.pyc +0 -0
- package/scripts/dashboard-api.py +14 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.71.0
|
|
Binary file
|
|
@@ -155,6 +155,7 @@ class ObsidianPersonaStore:
|
|
|
155
155
|
communication=PersonaCommunication(
|
|
156
156
|
**_filter_known(PersonaCommunication, comm_fm),
|
|
157
157
|
),
|
|
158
|
+
bio_md=str(fm.get("bio_md") or ""),
|
|
158
159
|
created_at=str(fm.get("created_at") or ""),
|
|
159
160
|
updated_at=str(fm.get("updated_at") or ""),
|
|
160
161
|
)
|
|
@@ -236,6 +237,12 @@ class ObsidianPersonaStore:
|
|
|
236
237
|
"created_at": persona.created_at or now,
|
|
237
238
|
"updated_at": now,
|
|
238
239
|
}
|
|
240
|
+
# v3.70.10 — long-form Markdown bio. Stored as a frontmatter
|
|
241
|
+
# block scalar so it survives round-trips; only emitted when set
|
|
242
|
+
# to keep bio-less persona files clean. YAML handles the multi-line
|
|
243
|
+
# value; the no-yaml fallback below can't, so skip it there.
|
|
244
|
+
if persona.bio_md and yaml is not None:
|
|
245
|
+
frontmatter["bio_md"] = persona.bio_md
|
|
239
246
|
if yaml is not None:
|
|
240
247
|
fm_block = yaml.safe_dump(
|
|
241
248
|
frontmatter,
|
|
Binary file
|
package/core/terminal/session.py
CHANGED
|
@@ -46,6 +46,13 @@ def _default_cwd() -> str:
|
|
|
46
46
|
return os.path.expanduser("~")
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
# v3.71.0 — in-memory scrollback so a reconnecting client (after the
|
|
50
|
+
# operator navigates away or reloads the dashboard) can replay recent
|
|
51
|
+
# output and find its session as it left it. Bounded, RAM-only, cleared
|
|
52
|
+
# on close, never written to disk and never sent to the audit log.
|
|
53
|
+
DEFAULT_SCROLLBACK_BYTES = 512 * 1024
|
|
54
|
+
|
|
55
|
+
|
|
49
56
|
class TerminalSession:
|
|
50
57
|
"""A single forked PTY + the bookkeeping needed to drive it.
|
|
51
58
|
|
|
@@ -60,6 +67,7 @@ class TerminalSession:
|
|
|
60
67
|
cwd: str,
|
|
61
68
|
cols: int = 120,
|
|
62
69
|
rows: int = 32,
|
|
70
|
+
scrollback_bytes: int = DEFAULT_SCROLLBACK_BYTES,
|
|
63
71
|
) -> None:
|
|
64
72
|
self.session_id = session_id
|
|
65
73
|
self.shell = shell
|
|
@@ -68,6 +76,8 @@ class TerminalSession:
|
|
|
68
76
|
self.last_activity = time.monotonic()
|
|
69
77
|
self.exit_code: Optional[int] = None
|
|
70
78
|
self.title: str = ""
|
|
79
|
+
self.scrollback_max = max(0, int(scrollback_bytes))
|
|
80
|
+
self._scrollback = bytearray()
|
|
71
81
|
self._closed = False
|
|
72
82
|
self.pid, self.master_fd = pty.fork()
|
|
73
83
|
if self.pid == 0:
|
|
@@ -104,8 +114,21 @@ class TerminalSession:
|
|
|
104
114
|
raise
|
|
105
115
|
if data:
|
|
106
116
|
self.last_activity = time.monotonic()
|
|
117
|
+
self._record(data)
|
|
107
118
|
return data
|
|
108
119
|
|
|
120
|
+
def _record(self, data: bytes) -> None:
|
|
121
|
+
"""Append output to the bounded scrollback, evicting the oldest."""
|
|
122
|
+
if self.scrollback_max <= 0:
|
|
123
|
+
return
|
|
124
|
+
self._scrollback += data
|
|
125
|
+
if len(self._scrollback) > self.scrollback_max:
|
|
126
|
+
del self._scrollback[: -self.scrollback_max]
|
|
127
|
+
|
|
128
|
+
def scrollback(self) -> bytes:
|
|
129
|
+
"""Snapshot of recent output, for replay on (re)connect."""
|
|
130
|
+
return bytes(self._scrollback)
|
|
131
|
+
|
|
109
132
|
def write(self, data: bytes) -> int:
|
|
110
133
|
if self._closed or self.master_fd < 0 or not data:
|
|
111
134
|
return 0
|
|
@@ -172,6 +195,7 @@ class TerminalSession:
|
|
|
172
195
|
except OSError:
|
|
173
196
|
pass
|
|
174
197
|
self.master_fd = -1
|
|
198
|
+
self._scrollback.clear()
|
|
175
199
|
self._closed = True
|
|
176
200
|
|
|
177
201
|
def to_dict(self) -> dict[str, Any]:
|
|
@@ -207,6 +231,9 @@ class TerminalSessionManager:
|
|
|
207
231
|
self.idle_timeout_s = int(
|
|
208
232
|
os.environ.get("ARKAOS_TERMINAL_IDLE_S", idle_default)
|
|
209
233
|
)
|
|
234
|
+
self.scrollback_bytes = int(
|
|
235
|
+
os.environ.get("ARKAOS_TERMINAL_SCROLLBACK_BYTES", DEFAULT_SCROLLBACK_BYTES)
|
|
236
|
+
)
|
|
210
237
|
self._sessions: dict[str, TerminalSession] = {}
|
|
211
238
|
|
|
212
239
|
def create(
|
|
@@ -230,6 +257,7 @@ class TerminalSessionManager:
|
|
|
230
257
|
cwd=chosen_cwd,
|
|
231
258
|
cols=cols,
|
|
232
259
|
rows=rows,
|
|
260
|
+
scrollback_bytes=self.scrollback_bytes,
|
|
233
261
|
)
|
|
234
262
|
self._sessions[sid] = session
|
|
235
263
|
audit.log_start(sid, chosen_shell, chosen_cwd)
|