@dmsdc-ai/aterm-darwin-arm64 0.1.57 → 0.1.59
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.
|
Binary file
|
|
Binary file
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
set -euo pipefail
|
|
5
5
|
|
|
6
6
|
# Ensure aterm Resources/bin is in PATH (survives shell PATH reset)
|
|
7
|
-
if [
|
|
7
|
+
if [ -n "${ATERM_RESOURCES_BIN:-}" ] && [ -d "$ATERM_RESOURCES_BIN" ]; then
|
|
8
8
|
case ":$PATH:" in
|
|
9
9
|
*":$ATERM_RESOURCES_BIN:"*) ;;
|
|
10
10
|
*) export PATH="$ATERM_RESOURCES_BIN:$PATH" ;;
|
|
@@ -16,11 +16,10 @@ ATERM_IPC_SOCKET="${ATERM_IPC_SOCKET:-}"
|
|
|
16
16
|
detect_ui_lang() {
|
|
17
17
|
local raw="${ATERM_UI_LANG:-${LC_ALL:-${LC_MESSAGES:-${LANG:-}}}}"
|
|
18
18
|
raw="$(printf '%s' "$raw" | tr '[:upper:]' '[:lower:]')"
|
|
19
|
-
|
|
20
|
-
echo "ko"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
fi
|
|
19
|
+
case "$raw" in
|
|
20
|
+
ko*|*ko_*|*ko-*) echo "ko" ;;
|
|
21
|
+
*) echo "en" ;;
|
|
22
|
+
esac
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
ATERM_UI_LANG="$(detect_ui_lang)"
|
|
@@ -48,7 +47,7 @@ ensure_lessons_file() {
|
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
print_ecosystem_status() {
|
|
51
|
-
if [
|
|
50
|
+
if [ "$ATERM_UI_LANG" = "ko" ]; then
|
|
52
51
|
cat <<'STATUS'
|
|
53
52
|
brain: ✅ 설치됨
|
|
54
53
|
telepty: ✅ 설치됨
|
|
@@ -66,7 +65,7 @@ STATUS
|
|
|
66
65
|
}
|
|
67
66
|
|
|
68
67
|
show_help() {
|
|
69
|
-
if [
|
|
68
|
+
if [ "$ATERM_UI_LANG" = "ko" ]; then
|
|
70
69
|
cat <<'HELP'
|
|
71
70
|
# aterm — AI 네이티브 터미널 세션 통신
|
|
72
71
|
|
|
@@ -285,9 +284,16 @@ try:
|
|
|
285
284
|
sys.exit(1)
|
|
286
285
|
elif action == "list":
|
|
287
286
|
if __import__("os").environ.get("ATERM_LIST_JSON"):
|
|
288
|
-
|
|
287
|
+
sessions = [
|
|
288
|
+
session for session in resp.get("data", [])
|
|
289
|
+
if session.get("status") not in ("dead", "closing")
|
|
290
|
+
]
|
|
291
|
+
print(json.dumps({"sessions": sessions}))
|
|
289
292
|
else:
|
|
290
|
-
sessions =
|
|
293
|
+
sessions = [
|
|
294
|
+
session for session in resp.get("data", [])
|
|
295
|
+
if session.get("status") not in ("dead", "closing")
|
|
296
|
+
]
|
|
291
297
|
if not sessions:
|
|
292
298
|
print("(워크스페이스 없음)" if lang == "ko" else "(no workspaces)")
|
|
293
299
|
else:
|
|
@@ -326,7 +332,7 @@ finally:
|
|
|
326
332
|
|
|
327
333
|
case "${1:-help}" in
|
|
328
334
|
list)
|
|
329
|
-
if [
|
|
335
|
+
if [ "${2:-}" = "--json" ]; then
|
|
330
336
|
# JSON mode: output merged JSON
|
|
331
337
|
python3 -c '
|
|
332
338
|
import json, sys, os, subprocess, os.path
|
|
@@ -352,12 +358,15 @@ if sock:
|
|
|
352
358
|
s.close()
|
|
353
359
|
resp = json.loads(data.decode().strip().split("\n")[0])
|
|
354
360
|
for ws in resp.get("data", []):
|
|
361
|
+
if ws.get("status") in ("dead", "closing"):
|
|
362
|
+
continue
|
|
355
363
|
ws["terminal"] = "aterm"
|
|
356
364
|
ws.setdefault("name", os.path.basename(ws.get("cwd", "")) or ws.get("id", "?"))
|
|
357
365
|
sessions.append(ws)
|
|
358
366
|
except: pass
|
|
359
367
|
|
|
360
|
-
# 2. telepty external sessions (only if installed)
|
|
368
|
+
# 2. telepty external sessions (only if installed, deduplicated)
|
|
369
|
+
aterm_names = set(s.get("name", "") for s in sessions)
|
|
361
370
|
try:
|
|
362
371
|
result = subprocess.run(["telepty", "list", "--json"], capture_output=True, text=True, timeout=5)
|
|
363
372
|
if result.returncode == 0:
|
|
@@ -365,6 +374,8 @@ try:
|
|
|
365
374
|
for ts in (tdata if isinstance(tdata, list) else tdata.get("sessions", [])):
|
|
366
375
|
ts.setdefault("terminal", ts.get("terminal", "external"))
|
|
367
376
|
ts.setdefault("name", ts.get("id", "?"))
|
|
377
|
+
if ts.get("name", "") in aterm_names:
|
|
378
|
+
continue
|
|
368
379
|
sessions.append(ts)
|
|
369
380
|
except (FileNotFoundError, subprocess.TimeoutExpired, json.JSONDecodeError): pass
|
|
370
381
|
|
|
@@ -397,19 +408,24 @@ if sock:
|
|
|
397
408
|
s.close()
|
|
398
409
|
resp = json.loads(data.decode().strip().split("\n")[0])
|
|
399
410
|
for ws in resp.get("data", []):
|
|
411
|
+
if ws.get("status") in ("dead", "closing"):
|
|
412
|
+
continue
|
|
400
413
|
name = ws.get("name") or os.path.basename(ws.get("cwd", "")) or ws.get("id", "?")
|
|
401
414
|
cli = ws.get("cli", "")
|
|
402
415
|
cwd = ws.get("cwd", "")
|
|
403
416
|
sessions.append((name, cli, cwd, "aterm"))
|
|
404
417
|
except: pass
|
|
405
418
|
|
|
406
|
-
# 2. telepty external sessions (only if installed)
|
|
419
|
+
# 2. telepty external sessions (only if installed, deduplicated)
|
|
420
|
+
aterm_names = set(r[0] for r in sessions)
|
|
407
421
|
try:
|
|
408
422
|
result = subprocess.run(["telepty", "list", "--json"], capture_output=True, text=True, timeout=5)
|
|
409
423
|
if result.returncode == 0:
|
|
410
424
|
tdata = json.loads(result.stdout)
|
|
411
425
|
for ts in (tdata if isinstance(tdata, list) else tdata.get("sessions", [])):
|
|
412
426
|
name = ts.get("name") or ts.get("id", "?")
|
|
427
|
+
if name in aterm_names:
|
|
428
|
+
continue
|
|
413
429
|
cli = ts.get("cli", "")
|
|
414
430
|
cwd = ts.get("cwd", "")
|
|
415
431
|
terminal = ts.get("terminal", "external")
|
|
@@ -435,64 +451,144 @@ else:
|
|
|
435
451
|
'
|
|
436
452
|
fi ;;
|
|
437
453
|
inject)
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
454
|
+
shift
|
|
455
|
+
_force_flag=false
|
|
456
|
+
_no_report=false
|
|
457
|
+
_ref_flag=false
|
|
458
|
+
_from_sender=""
|
|
459
|
+
_inject_args=()
|
|
460
|
+
while [ "$#" -gt 0 ]; do
|
|
461
|
+
case "$1" in
|
|
462
|
+
--force) _force_flag=true; shift ;;
|
|
463
|
+
--no-report) _no_report=true; shift ;;
|
|
464
|
+
--ref) _ref_flag=true; shift ;;
|
|
465
|
+
--from) _from_sender="${2:-}"; shift 2 ;;
|
|
466
|
+
*) _inject_args+=("$1"); shift ;;
|
|
467
|
+
esac
|
|
444
468
|
done
|
|
445
|
-
[
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
469
|
+
[ ${#_inject_args[@]} -lt 2 ] && { echo '{"error":"usage: aterm inject [--from <sender>] [--ref] [--no-report] [--force] <workspace> <text>"}' >&2; exit 1; }
|
|
470
|
+
python3 -c '
|
|
471
|
+
import json, sys, os, hashlib, socket
|
|
472
|
+
|
|
473
|
+
force = sys.argv[1] == "true"
|
|
474
|
+
no_report = sys.argv[2] == "true"
|
|
475
|
+
ref_flag = sys.argv[3] == "true"
|
|
476
|
+
from_sender = sys.argv[4]
|
|
477
|
+
ipc_socket = sys.argv[5]
|
|
478
|
+
remaining = sys.argv[6:]
|
|
479
|
+
|
|
480
|
+
workspace = remaining[0]
|
|
481
|
+
msg = " ".join(remaining[1:])
|
|
482
|
+
|
|
483
|
+
# Read inject config
|
|
484
|
+
inject_cfg = {}
|
|
485
|
+
cfg_path = os.path.expanduser("~/.aigentry/config/aterm.json")
|
|
486
|
+
if os.path.isfile(cfg_path):
|
|
487
|
+
try:
|
|
488
|
+
with open(cfg_path) as f:
|
|
489
|
+
inject_cfg = json.load(f).get("inject", {})
|
|
490
|
+
except: pass
|
|
491
|
+
|
|
492
|
+
mandatory_report = inject_cfg.get("mandatory_report", True)
|
|
493
|
+
auto_ref_threshold = inject_cfg.get("auto_ref_threshold", 500)
|
|
494
|
+
|
|
495
|
+
# Append mandatory report instruction
|
|
496
|
+
if from_sender and mandatory_report and not no_report:
|
|
497
|
+
msg += "\n\n\u26a0\ufe0f MANDATORY: When done, you MUST immediately run: aterm inject " + from_sender + " \x27REPORT: {modified files} | {change summary} | {build result} | {remaining issues}\x27. Do NOT idle or wait \u2014 report is REQUIRED before any other action."
|
|
498
|
+
|
|
499
|
+
# Auto-ref for long messages
|
|
500
|
+
if ref_flag or len(msg) > auto_ref_threshold:
|
|
501
|
+
ref_dir = os.path.expanduser("~/.aterm/refs")
|
|
502
|
+
os.makedirs(ref_dir, exist_ok=True)
|
|
503
|
+
h = hashlib.sha256(msg.encode()).hexdigest()
|
|
504
|
+
ref_path = os.path.join(ref_dir, h + ".md")
|
|
505
|
+
with open(ref_path, "w") as f:
|
|
506
|
+
f.write(msg)
|
|
507
|
+
msg = "[context-ref] Read " + ref_path + " and use it as the source of truth for this task."
|
|
508
|
+
|
|
509
|
+
# Dispatch
|
|
510
|
+
if not ipc_socket:
|
|
511
|
+
cmd = ["telepty", "inject"]
|
|
512
|
+
if from_sender:
|
|
513
|
+
cmd += ["--from", from_sender]
|
|
514
|
+
cmd += [workspace, msg]
|
|
515
|
+
os.execvp("telepty", cmd)
|
|
516
|
+
else:
|
|
517
|
+
payload = {"action": "Inject", "workspace": workspace, "text": msg, "from": os.environ.get("ATERM_WORKSPACE_NAME")}
|
|
518
|
+
if force:
|
|
519
|
+
payload["force"] = True
|
|
520
|
+
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
521
|
+
try:
|
|
522
|
+
sock.settimeout(5)
|
|
523
|
+
sock.connect(ipc_socket)
|
|
524
|
+
sock.sendall((json.dumps(payload) + "\n").encode())
|
|
525
|
+
sock.shutdown(socket.SHUT_WR)
|
|
526
|
+
data = b""
|
|
527
|
+
while True:
|
|
528
|
+
chunk = sock.recv(4096)
|
|
529
|
+
if not chunk: break
|
|
530
|
+
data += chunk
|
|
531
|
+
if b"\n" in data: break
|
|
532
|
+
resp = json.loads(data.decode().strip().split("\n")[0])
|
|
533
|
+
if resp.get("status") == "Error":
|
|
534
|
+
print(json.dumps({"error": resp["message"]}), file=sys.stderr)
|
|
535
|
+
sys.exit(1)
|
|
536
|
+
else:
|
|
537
|
+
print(json.dumps({"status": "ok"}))
|
|
538
|
+
except Exception as e:
|
|
539
|
+
print(json.dumps({"error": str(e)}), file=sys.stderr)
|
|
540
|
+
sys.exit(1)
|
|
541
|
+
finally:
|
|
542
|
+
sock.close()
|
|
543
|
+
' "$_force_flag" "$_no_report" "$_ref_flag" "$_from_sender" "${ATERM_IPC_SOCKET:-}" "${_inject_args[@]}" ;;
|
|
451
544
|
status)
|
|
452
|
-
if [
|
|
545
|
+
if [ "$#" -eq 1 ]; then
|
|
453
546
|
print_ecosystem_status
|
|
454
547
|
exit 0
|
|
455
548
|
fi
|
|
456
|
-
if [
|
|
457
|
-
[
|
|
549
|
+
if [ -z "$ATERM_IPC_SOCKET" ]; then exec telepty status "${@:2}"; fi
|
|
550
|
+
[ "$#" -lt 2 ] && { echo '{"error":"usage: aterm status <workspace>"}' >&2; exit 1; }
|
|
458
551
|
aterm_ipc status "$2" ;;
|
|
459
552
|
focus)
|
|
460
|
-
[
|
|
461
|
-
[
|
|
553
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"focus requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
554
|
+
[ "$#" -lt 2 ] && { echo '{"error":"usage: aterm focus <workspace>"}' >&2; exit 1; }
|
|
462
555
|
aterm_ipc focus "$2" ;;
|
|
463
556
|
rename)
|
|
464
|
-
[
|
|
465
|
-
[
|
|
557
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"rename requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
558
|
+
[ "$#" -lt 3 ] && { echo '{"error":"usage: aterm rename <old> <new>"}' >&2; exit 1; }
|
|
466
559
|
aterm_ipc rename "$2" "$3" ;;
|
|
467
560
|
clear)
|
|
468
|
-
[
|
|
469
|
-
[
|
|
561
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"clear requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
562
|
+
[ "$#" -lt 2 ] && { echo '{"error":"usage: aterm clear <workspace>"}' >&2; exit 1; }
|
|
470
563
|
aterm_ipc clear "$2" ;;
|
|
471
564
|
create)
|
|
472
|
-
[
|
|
565
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"create requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
473
566
|
# Parse: aterm create <name> --cli <cli> --cwd <path>
|
|
474
567
|
shift
|
|
475
568
|
_name="${1:-}"; shift || true
|
|
476
569
|
_cli=""; _cwd=""
|
|
477
|
-
while [
|
|
570
|
+
while [ "$#" -gt 0 ]; do
|
|
478
571
|
case "$1" in
|
|
479
572
|
--cli) _cli="$2"; shift 2 ;;
|
|
480
573
|
--cwd) _cwd="$2"; shift 2 ;;
|
|
481
574
|
*) shift ;;
|
|
482
575
|
esac
|
|
483
576
|
done
|
|
484
|
-
[
|
|
577
|
+
if [ -z "$_name" ] || [ -z "$_cli" ] || [ -z "$_cwd" ]; then
|
|
578
|
+
echo '{"error":"usage: aterm create <name> --cli <cli> --cwd <path>"}' >&2
|
|
579
|
+
exit 1
|
|
580
|
+
fi
|
|
485
581
|
aterm_ipc create "$_name" "$_cli" "$_cwd" ;;
|
|
486
582
|
restart)
|
|
487
|
-
[
|
|
488
|
-
[
|
|
583
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"restart requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
584
|
+
[ "$#" -lt 2 ] && { echo '{"error":"usage: aterm restart <workspace>"}' >&2; exit 1; }
|
|
489
585
|
aterm_ipc restart "$2" ;;
|
|
490
586
|
kill)
|
|
491
|
-
[
|
|
492
|
-
[
|
|
587
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"kill requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
588
|
+
[ "$#" -lt 2 ] && { echo '{"error":"usage: aterm kill <workspace>"}' >&2; exit 1; }
|
|
493
589
|
aterm_ipc kill "$2" ;;
|
|
494
590
|
restart-all)
|
|
495
|
-
[
|
|
591
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"restart-all requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
496
592
|
aterm_ipc restart-all ;;
|
|
497
593
|
tasks)
|
|
498
594
|
ensure_tasks_file
|
|
@@ -510,7 +606,7 @@ for i, t in enumerate(data["tasks"]):
|
|
|
510
606
|
print(f" [{tid}] {desc}")
|
|
511
607
|
' "$(tasks_file)" ;;
|
|
512
608
|
add)
|
|
513
|
-
[
|
|
609
|
+
[ "$#" -lt 3 ] && { echo '{"error":"usage: aterm tasks add <description>"}' >&2; exit 1; }
|
|
514
610
|
python3 -c '
|
|
515
611
|
import json, sys, time
|
|
516
612
|
f = sys.argv[1]; desc = " ".join(sys.argv[2:])
|
|
@@ -521,7 +617,7 @@ with open(f, "w") as fh: json.dump(data, fh, indent=2, ensure_ascii=False); fh.w
|
|
|
521
617
|
print(json.dumps({"status":"ok","id": tid}))
|
|
522
618
|
' "$(tasks_file)" "${@:3}" ;;
|
|
523
619
|
done)
|
|
524
|
-
[
|
|
620
|
+
[ "$#" -lt 3 ] && { echo '{"error":"usage: aterm tasks done <id>"}' >&2; exit 1; }
|
|
525
621
|
python3 -c '
|
|
526
622
|
import json, sys
|
|
527
623
|
f = sys.argv[1]; target = int(sys.argv[2])
|
|
@@ -560,7 +656,7 @@ if fail:
|
|
|
560
656
|
for l in fail: print(f" - {l}")
|
|
561
657
|
' "$(lessons_file)" ;;
|
|
562
658
|
add)
|
|
563
|
-
[
|
|
659
|
+
[ "$#" -lt 3 ] && { echo '{"error":"usage: aterm lessons add <lesson> [--type invariant|failed]"}' >&2; exit 1; }
|
|
564
660
|
python3 -c '
|
|
565
661
|
import json, sys
|
|
566
662
|
f = sys.argv[1]; lesson = sys.argv[2]
|
|
@@ -577,7 +673,7 @@ print(json.dumps({"status":"ok","type": ltype}))
|
|
|
577
673
|
*) echo '{"error":"usage: aterm lessons [list|add]"}' >&2; exit 1 ;;
|
|
578
674
|
esac ;;
|
|
579
675
|
dispatch)
|
|
580
|
-
[
|
|
676
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"dispatch requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
581
677
|
python3 -c '
|
|
582
678
|
import socket
|
|
583
679
|
import subprocess
|
|
@@ -825,7 +921,7 @@ main()
|
|
|
825
921
|
settings)
|
|
826
922
|
case "${2:-}" in
|
|
827
923
|
get)
|
|
828
|
-
[
|
|
924
|
+
[ "$#" -lt 3 ] && { echo '{"error":"usage: aterm settings get <key>"}' >&2; exit 1; }
|
|
829
925
|
python3 -c '
|
|
830
926
|
import json, sys, os
|
|
831
927
|
f = os.path.expanduser("~/.aigentry/config/aterm.json")
|
|
@@ -849,7 +945,7 @@ else:
|
|
|
849
945
|
print(json.dumps(val))
|
|
850
946
|
' "$3" ;;
|
|
851
947
|
set)
|
|
852
|
-
[
|
|
948
|
+
[ "$#" -lt 4 ] && { echo '{"error":"usage: aterm settings set <key> <value>"}' >&2; exit 1; }
|
|
853
949
|
python3 -c '
|
|
854
950
|
import json, sys, os
|
|
855
951
|
f = os.path.expanduser("~/.aigentry/config/aterm.json")
|
|
@@ -874,13 +970,13 @@ with open(f, "w") as fh:
|
|
|
874
970
|
fh.write("\n")
|
|
875
971
|
print(json.dumps({"status": "ok", "key": key, "value": val}))
|
|
876
972
|
' "$3" "$4"
|
|
877
|
-
if [
|
|
973
|
+
if [ -n "$ATERM_IPC_SOCKET" ]; then
|
|
878
974
|
aterm_ipc reload-settings 2>/dev/null || true
|
|
879
975
|
fi ;;
|
|
880
976
|
*) echo '{"error":"usage: aterm settings [get|set]"}' >&2; exit 1 ;;
|
|
881
977
|
esac ;;
|
|
882
978
|
theme)
|
|
883
|
-
[
|
|
979
|
+
[ "$#" -lt 2 ] && { echo '{"error":"usage: aterm theme <name>"}' >&2; exit 1; }
|
|
884
980
|
python3 -c '
|
|
885
981
|
import json, sys, os
|
|
886
982
|
f = os.path.expanduser("~/.aigentry/config/aterm.json")
|
|
@@ -895,20 +991,20 @@ with open(f, "w") as fh:
|
|
|
895
991
|
fh.write("\n")
|
|
896
992
|
print(json.dumps({"status": "ok", "key": "colorScheme", "value": sys.argv[1]}))
|
|
897
993
|
' "$2"
|
|
898
|
-
if [
|
|
994
|
+
if [ -n "$ATERM_IPC_SOCKET" ]; then
|
|
899
995
|
aterm_ipc reload-settings 2>/dev/null || true
|
|
900
996
|
fi ;;
|
|
901
997
|
log)
|
|
902
|
-
[
|
|
903
|
-
[
|
|
998
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"log requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
999
|
+
[ "$#" -lt 2 ] && { echo '{"error":"usage: aterm log <workspace> [--lines N]"}' >&2; exit 1; }
|
|
904
1000
|
_ws="$2"; _lines=100
|
|
905
|
-
if [
|
|
1001
|
+
if [ "${3:-}" = "--lines" ] && [ -n "${4:-}" ]; then _lines="$4"; fi
|
|
906
1002
|
aterm_ipc read-screen "$_ws" "$_lines" ;;
|
|
907
1003
|
export)
|
|
908
|
-
[
|
|
909
|
-
[
|
|
1004
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"export requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
1005
|
+
[ "$#" -lt 2 ] && { echo '{"error":"usage: aterm export <workspace> [--format md|txt]"}' >&2; exit 1; }
|
|
910
1006
|
_ws="$2"; _fmt="txt"
|
|
911
|
-
if [
|
|
1007
|
+
if [ "${3:-}" = "--format" ] && [ -n "${4:-}" ]; then _fmt="$4"; fi
|
|
912
1008
|
python3 -c '
|
|
913
1009
|
import os, socket, sys, json, time
|
|
914
1010
|
|
|
@@ -947,19 +1043,19 @@ with open(filename, "w") as f:
|
|
|
947
1043
|
print(json.dumps({"status": "ok", "file": os.path.abspath(filename)}))
|
|
948
1044
|
' "$ATERM_IPC_SOCKET" "$_ws" "$_fmt" ;;
|
|
949
1045
|
attach)
|
|
950
|
-
[
|
|
951
|
-
[
|
|
1046
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"attach requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
1047
|
+
[ "$#" -lt 2 ] && { echo '{"error":"usage: aterm attach <external-id>"}' >&2; exit 1; }
|
|
952
1048
|
aterm_ipc attach-external "$2" ;;
|
|
953
1049
|
send-key)
|
|
954
|
-
[
|
|
955
|
-
[
|
|
1050
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"send-key requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
1051
|
+
[ "$#" -lt 3 ] && { echo '{"error":"usage: aterm send-key <workspace> <key>"}' >&2; exit 1; }
|
|
956
1052
|
aterm_ipc send-key "$2" "$3" ;;
|
|
957
1053
|
subscribe)
|
|
958
|
-
[
|
|
1054
|
+
[ -z "$ATERM_IPC_SOCKET" ] && { echo '{"error":"subscribe requires aterm (ATERM_IPC_SOCKET not set)"}' >&2; exit 1; }
|
|
959
1055
|
# Parse --events flag
|
|
960
1056
|
_events="[]"
|
|
961
1057
|
shift
|
|
962
|
-
while [
|
|
1058
|
+
while [ "$#" -gt 0 ]; do
|
|
963
1059
|
case "$1" in
|
|
964
1060
|
--events) _events="$2"; shift 2 ;;
|
|
965
1061
|
*) shift ;;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<dict>
|
|
7
7
|
<key>Resources/bin/aterm</key>
|
|
8
8
|
<data>
|
|
9
|
-
|
|
9
|
+
P/uIgNhm9toASMimI4RR0juDghA=
|
|
10
10
|
</data>
|
|
11
11
|
</dict>
|
|
12
12
|
<key>files2</key>
|
|
@@ -15,16 +15,16 @@
|
|
|
15
15
|
<dict>
|
|
16
16
|
<key>cdhash</key>
|
|
17
17
|
<data>
|
|
18
|
-
|
|
18
|
+
Sey+kIzbOnElCcNjq82gqWDjjV0=
|
|
19
19
|
</data>
|
|
20
20
|
<key>requirement</key>
|
|
21
|
-
<string>cdhash H"
|
|
21
|
+
<string>cdhash H"49ecbe908cdb3a712509c363abcda0a960e38d5d"</string>
|
|
22
22
|
</dict>
|
|
23
23
|
<key>Resources/bin/aterm</key>
|
|
24
24
|
<dict>
|
|
25
25
|
<key>hash2</key>
|
|
26
26
|
<data>
|
|
27
|
-
|
|
27
|
+
s5bUwTZCPnhDBHD2yJTrPYbiUW/tvS95Jp51csx2xCg=
|
|
28
28
|
</data>
|
|
29
29
|
</dict>
|
|
30
30
|
</dict>
|