@askexenow/exe-os 0.9.156 → 0.9.158

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 (131) hide show
  1. package/deploy/compose/PROTECTED_FILES.md +34 -0
  2. package/deploy/compose/backup.sh +99 -19
  3. package/deploy/compose/docker-compose.yml +6 -6
  4. package/deploy/compose/restore.sh +73 -0
  5. package/deploy/stack-manifests/v0.9.json +41 -2
  6. package/dist/{backfill-metadata-W7FUQRD7.js → backfill-metadata-CUNNA5MI.js} +1 -1
  7. package/dist/bin/agentic-ontology-backfill.js +1 -1
  8. package/dist/bin/agentic-reflection-backfill.js +1 -1
  9. package/dist/bin/agentic-semantic-label.js +1 -1
  10. package/dist/bin/backfill-conversations.js +1 -1
  11. package/dist/bin/backfill-responses.js +1 -1
  12. package/dist/bin/backfill-vectors.js +2 -2
  13. package/dist/bin/bulk-sync-postgres.js +1 -1
  14. package/dist/bin/cleanup-stale-review-tasks.js +2 -2
  15. package/dist/bin/cli.js +4 -4
  16. package/dist/bin/exe-assign.js +1 -1
  17. package/dist/bin/exe-boot.js +3 -3
  18. package/dist/bin/exe-dispatch.js +2 -2
  19. package/dist/bin/exe-doctor.js +1 -1
  20. package/dist/bin/exe-export-behaviors.js +2 -2
  21. package/dist/bin/exe-forget.js +3 -3
  22. package/dist/bin/exe-gateway.js +4 -4
  23. package/dist/bin/exe-heartbeat.js +2 -2
  24. package/dist/bin/exe-kill.js +3 -3
  25. package/dist/bin/exe-launch-agent.js +2 -2
  26. package/dist/bin/exe-pending-messages.js +3 -3
  27. package/dist/bin/exe-pending-notifications.js +2 -2
  28. package/dist/bin/exe-pending-reviews.js +2 -2
  29. package/dist/bin/exe-review.js +3 -3
  30. package/dist/bin/exe-search.js +2 -2
  31. package/dist/bin/exe-session-cleanup.js +7 -6
  32. package/dist/bin/exe-start-codex.js +2 -2
  33. package/dist/bin/exe-start-opencode.js +1 -1
  34. package/dist/bin/exe-status.js +3 -3
  35. package/dist/bin/exe-team.js +1 -1
  36. package/dist/bin/git-sweep.js +2 -2
  37. package/dist/bin/graph-backfill.js +1 -1
  38. package/dist/bin/graph-export.js +2 -2
  39. package/dist/bin/intercom-check.js +3 -3
  40. package/dist/bin/scan-tasks.js +2 -2
  41. package/dist/bin/shard-migrate.js +1 -1
  42. package/dist/bin/stack-update.js +27 -2
  43. package/dist/{capacity-monitor-WAZTZAR5.js → capacity-monitor-24CCEIJP.js} +2 -2
  44. package/dist/{catchup-brief-PKETW4ND.js → catchup-brief-QQUPS66I.js} +3 -3
  45. package/dist/{chunk-7XRGVVG6.js → chunk-3SQ6D4VK.js} +2 -2
  46. package/dist/{chunk-KZXC3G3P.js → chunk-47B5ZHTD.js} +1 -1
  47. package/dist/{chunk-6F46227N.js → chunk-4Q2OWCEU.js} +2 -2
  48. package/dist/{chunk-7VIH6LOQ.js → chunk-6OXHZIB6.js} +1 -1
  49. package/dist/{chunk-FOG7AEEO.js → chunk-6QQMF3AG.js} +1 -1
  50. package/dist/{chunk-3AN3RTUT.js → chunk-7DUZ3JFZ.js} +3 -3
  51. package/dist/{chunk-A6LSJC2O.js → chunk-7TV6RZLE.js} +1 -1
  52. package/dist/{chunk-U56WZR5E.js → chunk-AU4YZOTU.js} +3 -3
  53. package/dist/{chunk-AK7S4GRC.js → chunk-BED3IEEA.js} +1 -1
  54. package/dist/{chunk-TM3WWKNB.js → chunk-C6HHR6RL.js} +2 -2
  55. package/dist/{chunk-JYYWHPQC.js → chunk-HIMHVTER.js} +3 -3
  56. package/dist/{chunk-HDQJMTBG.js → chunk-JETWZJDU.js} +1 -1
  57. package/dist/{chunk-OCFYT3LE.js → chunk-LIYHRGAB.js} +22 -3
  58. package/dist/{chunk-JFEFVLLD.js → chunk-OMS7KJFD.js} +1 -1
  59. package/dist/{chunk-IRVLV6C5.js → chunk-P66GZHIS.js} +1 -1
  60. package/dist/{chunk-XIZR2YLR.js → chunk-QSQWOHS7.js} +22 -22
  61. package/dist/{chunk-RZE4KMRO.js → chunk-S3XTYXAG.js} +1 -1
  62. package/dist/{chunk-MBXAWOYB.js → chunk-SFQYCOJK.js} +1 -1
  63. package/dist/{chunk-BRHV6CJT.js → chunk-T25RLVTT.js} +1 -1
  64. package/dist/{chunk-23UPL4NU.js → chunk-TNW7GPEM.js} +2 -2
  65. package/dist/{chunk-HF6TVN2J.js → chunk-VEGDCI2M.js} +5 -5
  66. package/dist/{chunk-PY7QM2C7.js → chunk-WUVYHPLZ.js} +1 -1
  67. package/dist/{chunk-CGLSVN6N.js → chunk-YL5UVGMM.js} +1 -1
  68. package/dist/{chunk-HH6ZCDZH.js → chunk-YW7LDVCW.js} +2 -2
  69. package/dist/{crm-webhook-DGL6XEOQ.js → crm-webhook-7OPJC3KJ.js} +2 -2
  70. package/dist/{cto-delegation-gate-UFSXT2CA.js → cto-delegation-gate-OWFS6YCI.js} +1 -1
  71. package/dist/{daemon-orchestration-IP2LHJJK.js → daemon-orchestration-IMVQSOUF.js} +3 -3
  72. package/dist/{exe-export-LLKDWX7F.js → exe-export-WRRUZP7P.js} +1 -1
  73. package/dist/{exe-import-XVAR7ZVC.js → exe-import-XKQBNQPY.js} +1 -1
  74. package/dist/{fast-db-init-SMQC6S3C.js → fast-db-init-F4IPHJ23.js} +1 -1
  75. package/dist/gateway/index.js +8 -8
  76. package/dist/{git-task-sweep-NWHG3FWG.js → git-task-sweep-IAOWJBSG.js} +2 -2
  77. package/dist/hooks/bug-report-worker.js +3 -3
  78. package/dist/hooks/codex-stop-task-finalizer.js +3 -3
  79. package/dist/hooks/commit-complete.js +4 -4
  80. package/dist/hooks/error-recall.js +2 -2
  81. package/dist/hooks/ingest.js +2 -2
  82. package/dist/hooks/instructions-loaded.js +1 -1
  83. package/dist/hooks/notification.js +1 -1
  84. package/dist/hooks/post-compact.js +2 -2
  85. package/dist/hooks/post-tool-combined.js +2 -2
  86. package/dist/hooks/pre-compact.js +3 -3
  87. package/dist/hooks/pre-tool-use.js +6 -6
  88. package/dist/hooks/prompt-submit.js +8 -8
  89. package/dist/hooks/session-end.js +6 -6
  90. package/dist/hooks/session-start.js +5 -5
  91. package/dist/hooks/stop.js +5 -5
  92. package/dist/hooks/subagent-stop.js +2 -2
  93. package/dist/hooks/summary-worker.js +5 -5
  94. package/dist/index.js +9 -9
  95. package/dist/lib/consolidation.js +2 -2
  96. package/dist/lib/exe-daemon.js +11 -11
  97. package/dist/lib/hybrid-search.js +2 -2
  98. package/dist/lib/messaging.js +2 -2
  99. package/dist/lib/schedules.js +2 -2
  100. package/dist/lib/store.js +1 -1
  101. package/dist/lib/tasks.js +2 -2
  102. package/dist/lib/tmux-routing.js +1 -1
  103. package/dist/mcp/register-tools.js +20 -20
  104. package/dist/mcp/server.js +21 -21
  105. package/dist/mcp/tools/create-task.js +3 -3
  106. package/dist/mcp/tools/list-tasks.js +3 -3
  107. package/dist/mcp/tools/send-message.js +3 -3
  108. package/dist/mcp/tools/update-task.js +3 -3
  109. package/dist/{notifications-Z6Q2SEHP.js → notifications-VJPITPQ3.js} +1 -1
  110. package/dist/{orchestrator-RHJGFMAS.js → orchestrator-L6XE65KD.js} +2 -2
  111. package/dist/{review-polling-XUIKH7HF.js → review-polling-XLY35KOM.js} +2 -2
  112. package/dist/runtime/index.js +3 -3
  113. package/dist/{session-events-KURSY7LK.js → session-events-76JYQUF6.js} +2 -2
  114. package/dist/{session-scope-5MOCMTAM.js → session-scope-X4V5Q3OT.js} +1 -1
  115. package/dist/{task-enforcement-2WCWSZQ3.js → task-enforcement-T3QFAHOT.js} +1 -1
  116. package/dist/{task-scope-HW6BE2PI.js → task-scope-AJPW2PUM.js} +1 -1
  117. package/dist/{tasks-crud-WACRTPQK.js → tasks-crud-PIYGXNBH.js} +1 -1
  118. package/dist/{tasks-review-LIWD4PGN.js → tasks-review-MYFRICXX.js} +1 -1
  119. package/dist/tui/App.js +7 -7
  120. package/dist/{tui-data-UKFAWSNP.js → tui-data-4S3IDSXK.js} +1 -1
  121. package/dist/{worker-gate-NJRW5QYT.js → worker-gate-B5MEFZ55.js} +1 -1
  122. package/dist/{workflow-engine-ICAQJSYT.js → workflow-engine-PYGOBKLD.js} +2 -2
  123. package/package.json +1 -1
  124. package/release-notes.json +71 -71
  125. /package/dist/{chunk-U5GTF2JP.js → chunk-CB3AZW66.js} +0 -0
  126. /package/dist/{chunk-RTNRPBQP.js → chunk-CUHCGEHC.js} +0 -0
  127. /package/dist/{chunk-PYDL42BL.js → chunk-LJDQQYKZ.js} +0 -0
  128. /package/dist/{chunk-E5PVJXIP.js → chunk-PPGL2TMJ.js} +0 -0
  129. /package/dist/{core-memory-QRQ62AZY.js → core-memory-JXVJ7S5Q.js} +0 -0
  130. /package/dist/{exe-key-E3YOJ2ME.js → exe-key-OU6EXI5G.js} +0 -0
  131. /package/dist/{skill-refinement-JBZRPZKW.js → skill-refinement-4WWF5AML.js} +0 -0
@@ -0,0 +1,34 @@
1
+ # Protected Files — NEVER overwritten by stack-update
2
+
3
+ These files contain customer configuration. `exe-os stack-update` MUST NOT
4
+ touch them. If a file needs to change, the update should add a NEW file
5
+ and log a migration notice, not replace the existing one.
6
+
7
+ ## Config files (bind-mounted, customer-owned after first setup)
8
+ - `.env` — all secrets, tokens, passwords (PATCHED, never replaced)
9
+ - `gateway.json` — WhatsApp adapter config, account names
10
+ - `branding.json` — customer brand colors, fonts, logo
11
+ - `cloudflared/config.yml` — tunnel ID, credentials, ingress routes
12
+ - `cloudflared/*.json` — tunnel credential files
13
+
14
+ ## Data volumes (Docker managed, persist across updates)
15
+ - `postgres_data` — all database data (CRM, wiki, graph, raw, gateway)
16
+ - `gateway_data` — Baileys WhatsApp auth state (creds.json, sessions)
17
+ - `wiki_data` — uploaded documents, workspace storage
18
+ - `crm_data` — CRM local file storage
19
+ - `monitor_hub_data` — PocketBase data, alert history
20
+ - `monitor_agent_data` — agent metrics cache
21
+ - `redis_data` — CRM job queue, session cache
22
+ - `clickhouse_data` — CRM analytics
23
+ - `exe_os_data` — daemon state, SQLCipher memory DB
24
+
25
+ ## What CAN be updated safely
26
+ - Docker images (pulled, not built locally)
27
+ - `init-db.sql` (only runs on FIRST postgres boot, not on restarts)
28
+ - `docker-compose.yml` (can be replaced — it references configs by path)
29
+ - Deploy scripts (setup.sh, backup.sh, status.sh)
30
+
31
+ ## Golden rule
32
+ If `docker compose down && docker compose up -d` loses customer data
33
+ or config, the compose is WRONG. Volumes and bind mounts must survive
34
+ any container lifecycle operation EXCEPT `docker compose down -v`.
@@ -1,37 +1,117 @@
1
1
  #!/usr/bin/env bash
2
- # Automated backup for exe-os stack — runs daily via cron or systemd timer.
3
- # Backs up: postgres (all databases), gateway auth state, wiki storage.
2
+ # exe-os stack backup full data + config, portable to any destination.
3
+ #
4
+ # Usage:
5
+ # ./backup.sh # Backup to /opt/exe-backups/
6
+ # ./backup.sh --output /tmp/backup # Backup to custom dir
7
+ # ./backup.sh --download # Create backup + print download command
8
+ # ./backup.sh --upload-r2 # Backup + upload to Cloudflare R2
9
+ # ./backup.sh --upload-s3 s3://bucket # Backup + upload to S3
10
+ #
4
11
  set -euo pipefail
5
12
 
6
13
  BACKUP_DIR="${BACKUP_DIR:-/opt/exe-backups}"
7
14
  RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-7}"
8
15
  DATE=$(date +%Y%m%d-%H%M%S)
9
- COMPOSE_DIR="$(cd "$(dirname "$0")" && pwd)"
16
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
17
+ DOWNLOAD_MODE=false
18
+ UPLOAD_R2=false
19
+ UPLOAD_S3=""
20
+
21
+ while [[ $# -gt 0 ]]; do
22
+ case $1 in
23
+ --output) BACKUP_DIR="$2"; shift 2;;
24
+ --download) DOWNLOAD_MODE=true; shift;;
25
+ --upload-r2) UPLOAD_R2=true; shift;;
26
+ --upload-s3) UPLOAD_S3="$2"; shift 2;;
27
+ *) shift;;
28
+ esac
29
+ done
10
30
 
11
31
  mkdir -p "$BACKUP_DIR"
32
+ ARCHIVE="$BACKUP_DIR/exe-backup-$DATE"
33
+ mkdir -p "$ARCHIVE"
12
34
 
13
- echo "[backup] Starting exe-os stack backup ($DATE)"
35
+ echo "[backup] Starting exe-os full stack backup ($DATE)"
14
36
 
15
37
  # 1. Postgres dump (all databases)
16
38
  echo "[backup] Dumping postgres..."
17
- docker exec exe-db pg_dumpall -U exe > "$BACKUP_DIR/postgres-$DATE.sql" 2>/dev/null
18
- gzip "$BACKUP_DIR/postgres-$DATE.sql"
19
- echo "[backup] Postgres: $(du -h "$BACKUP_DIR/postgres-$DATE.sql.gz" | cut -f1)"
39
+ docker exec exe-db pg_dumpall -U exe > "$ARCHIVE/postgres.sql" 2>/dev/null || echo "[backup] Postgres dump failed"
40
+ gzip "$ARCHIVE/postgres.sql" 2>/dev/null || true
41
+
42
+ # 2. Customer config files (.env, gateway.json, branding.json, cloudflared)
43
+ echo "[backup] Backing up config files..."
44
+ cp "$SCRIPT_DIR/.env" "$ARCHIVE/env.bak" 2>/dev/null || true
45
+ cp "$SCRIPT_DIR/gateway.json" "$ARCHIVE/gateway.json" 2>/dev/null || true
46
+ cp "$SCRIPT_DIR/branding.json" "$ARCHIVE/branding.json" 2>/dev/null || true
47
+ cp -r "$SCRIPT_DIR/cloudflared" "$ARCHIVE/cloudflared" 2>/dev/null || true
20
48
 
21
- # 2. Gateway auth state (Baileys creds)
22
- echo "[backup] Backing up gateway auth state..."
23
- docker cp exe-gateway:/data/. "$BACKUP_DIR/gateway-$DATE/" 2>/dev/null || echo "[backup] Gateway backup skipped (not running)"
24
- tar -czf "$BACKUP_DIR/gateway-$DATE.tar.gz" -C "$BACKUP_DIR" "gateway-$DATE" 2>/dev/null && rm -rf "$BACKUP_DIR/gateway-$DATE"
49
+ # 3. Gateway auth state (Baileys creds — critical for WhatsApp connection)
50
+ echo "[backup] Backing up gateway WhatsApp auth state..."
51
+ docker cp exe-gateway:/data/. "$ARCHIVE/gateway-data/" 2>/dev/null || echo "[backup] Gateway data skipped"
25
52
 
26
- # 3. Wiki storage (uploaded docs)
53
+ # 4. Wiki storage (uploaded documents)
27
54
  echo "[backup] Backing up wiki storage..."
28
- docker cp exe-wiki:/app/server/storage/. "$BACKUP_DIR/wiki-$DATE/" 2>/dev/null || echo "[backup] Wiki backup skipped"
29
- tar -czf "$BACKUP_DIR/wiki-$DATE.tar.gz" -C "$BACKUP_DIR" "wiki-$DATE" 2>/dev/null && rm -rf "$BACKUP_DIR/wiki-$DATE"
55
+ docker cp exe-wiki:/app/server/storage/. "$ARCHIVE/wiki-storage/" 2>/dev/null || echo "[backup] Wiki storage skipped"
56
+
57
+ # 5. exe-os daemon state (optional — SQLCipher DB is local-first, not critical for VPS)
58
+ echo "[backup] Backing up exe-os state..."
59
+ docker cp exe-os:/home/exed/.exe-os/. "$ARCHIVE/exe-os-data/" 2>/dev/null || echo "[backup] exe-os data skipped"
60
+
61
+ # 6. Create single archive
62
+ echo "[backup] Creating archive..."
63
+ TARFILE="$BACKUP_DIR/exe-backup-$DATE.tar.gz"
64
+ tar -czf "$TARFILE" -C "$BACKUP_DIR" "exe-backup-$DATE" 2>/dev/null
65
+ rm -rf "$ARCHIVE"
66
+ echo "[backup] Archive: $TARFILE ($(du -h "$TARFILE" | cut -f1))"
30
67
 
31
- # 4. Retention — delete backups older than N days
68
+ # 7. Retention — delete old backups
32
69
  echo "[backup] Cleaning backups older than $RETENTION_DAYS days..."
33
- find "$BACKUP_DIR" -name "*.gz" -mtime "+$RETENTION_DAYS" -delete 2>/dev/null
34
- find "$BACKUP_DIR" -name "*.sql" -mtime "+$RETENTION_DAYS" -delete 2>/dev/null
70
+ find "$BACKUP_DIR" -name "exe-backup-*.tar.gz" -mtime "+$RETENTION_DAYS" -delete 2>/dev/null
71
+
72
+ # 8. Download instructions
73
+ if $DOWNLOAD_MODE; then
74
+ echo ""
75
+ echo "=== Download to your local machine ==="
76
+ echo "Run on your local machine:"
77
+ echo ""
78
+ HOSTNAME=$(hostname)
79
+ IP=$(curl -s ifconfig.me 2>/dev/null || echo "<VPS_IP>")
80
+ echo " scp root@$IP:$TARFILE ./exe-backup-$DATE.tar.gz"
81
+ echo ""
82
+ echo "Or via Tailscale:"
83
+ TS_IP=$(tailscale ip -4 2>/dev/null || echo "<TAILSCALE_IP>")
84
+ echo " scp root@$TS_IP:$TARFILE ./exe-backup-$DATE.tar.gz"
85
+ echo ""
86
+ echo "To restore on a new VPS:"
87
+ echo " tar -xzf exe-backup-$DATE.tar.gz"
88
+ echo " cp env.bak /opt/exe-stack/.env"
89
+ echo " cp gateway.json /opt/exe-stack/"
90
+ echo " cp branding.json /opt/exe-stack/"
91
+ echo " cp -r cloudflared/ /opt/exe-stack/"
92
+ echo " cat postgres.sql.gz | gunzip | docker exec -i exe-db psql -U exe"
93
+ echo " docker compose up -d"
94
+ fi
95
+
96
+ # 9. Upload to R2 (Cloudflare)
97
+ if $UPLOAD_R2; then
98
+ echo "[backup] Uploading to Cloudflare R2..."
99
+ if command -v rclone >/dev/null 2>&1; then
100
+ rclone copy "$TARFILE" r2:exe-backups/ 2>&1 && echo "[backup] R2 upload complete" || echo "[backup] R2 upload failed"
101
+ elif command -v aws >/dev/null 2>&1; then
102
+ aws s3 cp "$TARFILE" "s3://exe-backups/$(basename "$TARFILE")" --endpoint-url "${R2_ENDPOINT:-}" 2>&1 || echo "[backup] R2 upload failed — configure R2_ENDPOINT"
103
+ else
104
+ echo "[backup] Install rclone or aws-cli for R2 upload"
105
+ fi
106
+ fi
107
+
108
+ # 10. Upload to S3
109
+ if [[ -n "$UPLOAD_S3" ]]; then
110
+ echo "[backup] Uploading to S3..."
111
+ aws s3 cp "$TARFILE" "$UPLOAD_S3/$(basename "$TARFILE")" 2>&1 && echo "[backup] S3 upload complete" || echo "[backup] S3 upload failed"
112
+ fi
35
113
 
36
- echo "[backup] Done. Backups at $BACKUP_DIR:"
37
- ls -lh "$BACKUP_DIR"/*.gz 2>/dev/null | tail -5
114
+ echo "[backup] Done."
115
+ echo ""
116
+ echo "Backups:"
117
+ ls -lh "$BACKUP_DIR"/exe-backup-*.tar.gz 2>/dev/null | tail -5
@@ -175,7 +175,7 @@ services:
175
175
  # ------------------------------------------------------------------
176
176
 
177
177
  exe-crm:
178
- image: ${CRM_IMAGE_TAG:-ghcr.io/askexe/exe-crm:v0.9.2}
178
+ image: ${CRM_IMAGE_TAG:-ghcr.io/askexe/exe-crm:v0.9.4}
179
179
  container_name: exe-crm
180
180
  restart: unless-stopped
181
181
  # Auto-migrate on boot: run database init before starting the app.
@@ -228,7 +228,7 @@ services:
228
228
  options: { max-size: "10m", max-file: "3" }
229
229
 
230
230
  exe-crm-worker:
231
- image: ${CRM_IMAGE_TAG:-ghcr.io/askexe/exe-crm:v0.9.2}
231
+ image: ${CRM_IMAGE_TAG:-ghcr.io/askexe/exe-crm:v0.9.4}
232
232
  container_name: exe-crm-worker
233
233
  restart: unless-stopped
234
234
  command: ["yarn", "worker:prod"]
@@ -268,7 +268,7 @@ services:
268
268
  options: { max-size: "10m", max-file: "3" }
269
269
 
270
270
  exe-wiki:
271
- image: ${WIKI_IMAGE_TAG:-ghcr.io/askexe/exe-wiki:v0.9.2}
271
+ image: ${WIKI_IMAGE_TAG:-ghcr.io/askexe/exe-wiki:v0.9.5}
272
272
  container_name: exe-wiki
273
273
  restart: unless-stopped
274
274
  # Wiki uses Prisma — runs migrate on boot via built-in entrypoint.
@@ -316,7 +316,7 @@ services:
316
316
  options: { max-size: "10m", max-file: "3" }
317
317
 
318
318
  exe-os:
319
- image: ${EXE_OS_IMAGE_TAG:-${EXED_IMAGE_TAG:-ghcr.io/askexe/exe-os:v0.9.2}}
319
+ image: ${EXE_OS_IMAGE_TAG:-${EXED_IMAGE_TAG:-ghcr.io/askexe/exe-os:v0.9.157}}
320
320
  container_name: exe-os
321
321
  restart: unless-stopped
322
322
  env_file:
@@ -352,7 +352,7 @@ services:
352
352
  options: { max-size: "10m", max-file: "3" }
353
353
 
354
354
  exe-gateway:
355
- image: ${GATEWAY_IMAGE_TAG:-ghcr.io/askexe/exe-gateway:v0.9.2}
355
+ image: ${GATEWAY_IMAGE_TAG:-ghcr.io/askexe/exe-gateway:v0.9.4}
356
356
  container_name: exe-gateway
357
357
  restart: unless-stopped
358
358
  depends_on:
@@ -404,7 +404,7 @@ services:
404
404
  options: { max-size: "10m", max-file: "3" }
405
405
 
406
406
  exe-monitor-agent:
407
- image: ${MONITOR_AGENT_IMAGE_TAG:-ghcr.io/askexe/exe-monitor-agent:v0.9.2}
407
+ image: ${MONITOR_AGENT_IMAGE_TAG:-ghcr.io/askexe/exe-monitor-agent:v0.9.4}
408
408
  container_name: exe-monitor-agent
409
409
  restart: unless-stopped
410
410
  environment:
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env bash
2
+ # exe-os stack restore — restore from a backup archive.
3
+ #
4
+ # Usage:
5
+ # ./restore.sh /path/to/exe-backup-YYYYMMDD-HHMMSS.tar.gz
6
+ #
7
+ # WARNING: This overwrites current config and database. Make a backup first.
8
+ set -euo pipefail
9
+
10
+ RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
11
+ info() { echo -e "${GREEN}[restore]${NC} $1"; }
12
+ warn() { echo -e "${YELLOW}[restore]${NC} $1"; }
13
+ err() { echo -e "${RED}[restore]${NC} $1" >&2; }
14
+
15
+ ARCHIVE="${1:-}"
16
+ [[ -z "$ARCHIVE" ]] && { err "Usage: ./restore.sh <backup-archive.tar.gz>"; exit 1; }
17
+ [[ ! -f "$ARCHIVE" ]] && { err "File not found: $ARCHIVE"; exit 1; }
18
+
19
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
20
+ TEMP_DIR=$(mktemp -d)
21
+ trap "rm -rf $TEMP_DIR" EXIT
22
+
23
+ info "Extracting backup..."
24
+ tar -xzf "$ARCHIVE" -C "$TEMP_DIR"
25
+ BACKUP_DIR=$(ls -d "$TEMP_DIR"/exe-backup-* 2>/dev/null | head -1)
26
+ [[ -z "$BACKUP_DIR" ]] && { err "Invalid backup archive — no exe-backup-* directory found"; exit 1; }
27
+
28
+ echo ""
29
+ warn "This will OVERWRITE current config and restore the database."
30
+ warn "Current data will be LOST. Make sure you have a backup of the current state."
31
+ read -p "Type 'RESTORE' to confirm: " CONFIRM
32
+ [[ "$CONFIRM" != "RESTORE" ]] && { err "Aborted."; exit 1; }
33
+
34
+ # 1. Restore config files
35
+ info "Restoring config files..."
36
+ [[ -f "$BACKUP_DIR/env.bak" ]] && cp "$BACKUP_DIR/env.bak" "$SCRIPT_DIR/.env" && info ".env restored"
37
+ [[ -f "$BACKUP_DIR/gateway.json" ]] && cp "$BACKUP_DIR/gateway.json" "$SCRIPT_DIR/gateway.json" && info "gateway.json restored"
38
+ [[ -f "$BACKUP_DIR/branding.json" ]] && cp "$BACKUP_DIR/branding.json" "$SCRIPT_DIR/branding.json" && info "branding.json restored"
39
+ [[ -d "$BACKUP_DIR/cloudflared" ]] && cp -r "$BACKUP_DIR/cloudflared" "$SCRIPT_DIR/" && info "cloudflared config restored"
40
+
41
+ # 2. Restore postgres
42
+ if [[ -f "$BACKUP_DIR/postgres.sql.gz" ]]; then
43
+ info "Restoring postgres database..."
44
+ docker compose up -d exe-db 2>/dev/null
45
+ sleep 5 # wait for postgres to be ready
46
+ gunzip -c "$BACKUP_DIR/postgres.sql.gz" | docker exec -i exe-db psql -U exe 2>/dev/null
47
+ info "Postgres restored"
48
+ fi
49
+
50
+ # 3. Restore gateway auth state
51
+ if [[ -d "$BACKUP_DIR/gateway-data" ]]; then
52
+ info "Restoring gateway WhatsApp auth state..."
53
+ docker compose up -d exe-gateway 2>/dev/null
54
+ sleep 3
55
+ docker cp "$BACKUP_DIR/gateway-data/." exe-gateway:/data/ 2>/dev/null
56
+ docker restart exe-gateway 2>/dev/null
57
+ info "Gateway auth state restored (WhatsApp should reconnect)"
58
+ fi
59
+
60
+ # 4. Restore wiki storage
61
+ if [[ -d "$BACKUP_DIR/wiki-storage" ]]; then
62
+ info "Restoring wiki storage..."
63
+ docker compose up -d exe-wiki 2>/dev/null
64
+ sleep 3
65
+ docker cp "$BACKUP_DIR/wiki-storage/." exe-wiki:/app/server/storage/ 2>/dev/null
66
+ info "Wiki storage restored"
67
+ fi
68
+
69
+ # 5. Start full stack
70
+ info "Starting full stack..."
71
+ docker compose up -d 2>&1
72
+
73
+ info "Restore complete. Run ./status.sh to verify."
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "latest": "0.9.9",
3
+ "latest": "0.9.10",
4
4
  "stacks": {
5
5
  "0.9.0": {
6
6
  "version": "0.9.0",
@@ -575,6 +575,45 @@
575
575
  "deploymentScope": "customer"
576
576
  }
577
577
  }
578
+ },
579
+ "0.9.10": {
580
+ "version": "0.9.10",
581
+ "releasedAt": "2026-05-29T00:00:00Z",
582
+ "notes": "Major update: unified auth (GoTrue + admin tokens), single postgres, graph schema rename, data pipeline, session scoping fixes, Codex task wakeup fix, deployment readiness (29 blind spots).",
583
+ "npmVersion": "0.9.157",
584
+ "breakingChanges": [],
585
+ "services": {
586
+ "crm": {
587
+ "image": "ghcr.io/askexe/exe-crm:v0.9.4",
588
+ "env": "CRM_IMAGE_TAG",
589
+ "composeService": "exe-crm"
590
+ },
591
+ "wiki": {
592
+ "image": "ghcr.io/askexe/exe-wiki:v0.9.5",
593
+ "env": "WIKI_IMAGE_TAG",
594
+ "composeService": "exe-wiki"
595
+ },
596
+ "exe-os": {
597
+ "image": "ghcr.io/askexe/exe-os:v0.9.157",
598
+ "env": "EXE_OS_IMAGE_TAG",
599
+ "composeService": "exe-os"
600
+ },
601
+ "gateway": {
602
+ "image": "ghcr.io/askexe/exe-gateway:v0.9.4",
603
+ "env": "GATEWAY_IMAGE_TAG",
604
+ "composeService": "exe-gateway"
605
+ },
606
+ "monitorAgent": {
607
+ "image": "ghcr.io/askexe/exe-monitor-agent:v0.9.4",
608
+ "env": "MONITOR_AGENT_IMAGE_TAG",
609
+ "composeService": "exe-monitor-agent"
610
+ },
611
+ "monitorHub": {
612
+ "image": "ghcr.io/askexe/exe-monitor-hub:v0.9.5",
613
+ "env": "MONITOR_HUB_IMAGE_TAG",
614
+ "composeService": "exe-monitor-hub"
615
+ }
616
+ }
578
617
  }
579
618
  }
580
- }
619
+ }
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  disposeStore,
4
4
  initStore
5
- } from "./chunk-RTNRPBQP.js";
5
+ } from "./chunk-CUHCGEHC.js";
6
6
  import "./chunk-LZLXG7TK.js";
7
7
  import "./chunk-MP2AFCGL.js";
8
8
  import {
@@ -9,7 +9,7 @@ import {
9
9
  import {
10
10
  disposeStore,
11
11
  initStore
12
- } from "../chunk-RTNRPBQP.js";
12
+ } from "../chunk-CUHCGEHC.js";
13
13
  import "../chunk-LZLXG7TK.js";
14
14
  import "../chunk-MP2AFCGL.js";
15
15
  import {
@@ -8,7 +8,7 @@ import {
8
8
  } from "../chunk-CTOQYEKJ.js";
9
9
  import {
10
10
  initStore
11
- } from "../chunk-RTNRPBQP.js";
11
+ } from "../chunk-CUHCGEHC.js";
12
12
  import "../chunk-LZLXG7TK.js";
13
13
  import "../chunk-MP2AFCGL.js";
14
14
  import "../chunk-EVB53OQD.js";
@@ -10,7 +10,7 @@ import {
10
10
  } from "../chunk-CTOQYEKJ.js";
11
11
  import {
12
12
  initStore
13
- } from "../chunk-RTNRPBQP.js";
13
+ } from "../chunk-CUHCGEHC.js";
14
14
  import "../chunk-LZLXG7TK.js";
15
15
  import "../chunk-MP2AFCGL.js";
16
16
  import {
@@ -9,7 +9,7 @@ import {
9
9
  flushBatch,
10
10
  initStore,
11
11
  writeMemory
12
- } from "../chunk-RTNRPBQP.js";
12
+ } from "../chunk-CUHCGEHC.js";
13
13
  import "../chunk-LZLXG7TK.js";
14
14
  import "../chunk-MP2AFCGL.js";
15
15
  import {
@@ -9,7 +9,7 @@ import {
9
9
  flushBatch,
10
10
  initStore,
11
11
  writeMemory
12
- } from "../chunk-RTNRPBQP.js";
12
+ } from "../chunk-CUHCGEHC.js";
13
13
  import "../chunk-LZLXG7TK.js";
14
14
  import "../chunk-MP2AFCGL.js";
15
15
  import {
@@ -8,7 +8,7 @@ import {
8
8
  registerWorkerPid,
9
9
  releaseBackfillLock,
10
10
  tryAcquireBackfillLock
11
- } from "../chunk-7VIH6LOQ.js";
11
+ } from "../chunk-6OXHZIB6.js";
12
12
  import {
13
13
  connectEmbedDaemon,
14
14
  embedViaClient
@@ -18,7 +18,7 @@ import "../chunk-CMFLJNP6.js";
18
18
  import {
19
19
  initStore,
20
20
  vectorToBlob
21
- } from "../chunk-RTNRPBQP.js";
21
+ } from "../chunk-CUHCGEHC.js";
22
22
  import "../chunk-LZLXG7TK.js";
23
23
  import "../chunk-MP2AFCGL.js";
24
24
  import {
@@ -7,7 +7,7 @@ import "../chunk-HOKOOBDL.js";
7
7
  import {
8
8
  disposeStore,
9
9
  initStore
10
- } from "../chunk-RTNRPBQP.js";
10
+ } from "../chunk-CUHCGEHC.js";
11
11
  import "../chunk-LZLXG7TK.js";
12
12
  import "../chunk-MP2AFCGL.js";
13
13
  import {
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  fastDbInit
4
- } from "../chunk-PYDL42BL.js";
4
+ } from "../chunk-LJDQQYKZ.js";
5
5
  import {
6
6
  sessionScopeFilter
7
- } from "../chunk-OCFYT3LE.js";
7
+ } from "../chunk-LIYHRGAB.js";
8
8
  import "../chunk-LOQCOHEW.js";
9
9
  import "../chunk-TXSJ2L5O.js";
10
10
  import "../chunk-64WZEXXA.js";
package/dist/bin/cli.js CHANGED
@@ -107,7 +107,7 @@ if (args.includes("--global")) {
107
107
  process.exit(1);
108
108
  }
109
109
  } else if (args[0] === "key") {
110
- const { main: runKey } = await import("../exe-key-E3YOJ2ME.js");
110
+ const { main: runKey } = await import("../exe-key-OU6EXI5G.js");
111
111
  await runKey(args.slice(1));
112
112
  } else if (args[0] === "link") {
113
113
  console.error("`exe-os link` has been removed from the customer command surface.");
@@ -147,7 +147,7 @@ if (args.includes("--global")) {
147
147
  process.exit(1);
148
148
  }
149
149
  } else if (args[0] === "backfill-metadata") {
150
- const { backfillMetadata } = await import("../backfill-metadata-W7FUQRD7.js");
150
+ const { backfillMetadata } = await import("../backfill-metadata-CUNNA5MI.js");
151
151
  let batchSize = 50;
152
152
  let limit = 0;
153
153
  let dryRun = false;
@@ -178,10 +178,10 @@ if (args.includes("--global")) {
178
178
  process.exit(1);
179
179
  }
180
180
  } else if (args[0] === "export") {
181
- const { runExeExport } = await import("../exe-export-LLKDWX7F.js");
181
+ const { runExeExport } = await import("../exe-export-WRRUZP7P.js");
182
182
  await runExeExport(args.slice(1));
183
183
  } else if (args[0] === "import") {
184
- const { runExeImport } = await import("../exe-import-XVAR7ZVC.js");
184
+ const { runExeImport } = await import("../exe-import-XKQBNQPY.js");
185
185
  await runExeImport(args.slice(1));
186
186
  } else if (args[0] === "send-message" || args[0] === "send_message") {
187
187
  const target = args[1];
@@ -10,7 +10,7 @@ import {
10
10
  initStore,
11
11
  searchMemories,
12
12
  writeMemory
13
- } from "../chunk-RTNRPBQP.js";
13
+ } from "../chunk-CUHCGEHC.js";
14
14
  import "../chunk-LZLXG7TK.js";
15
15
  import {
16
16
  createAssignmentMemory,
@@ -14,7 +14,7 @@ import {
14
14
  } from "../chunk-77QEF6FR.js";
15
15
  import {
16
16
  initStore
17
- } from "../chunk-RTNRPBQP.js";
17
+ } from "../chunk-CUHCGEHC.js";
18
18
  import "../chunk-LZLXG7TK.js";
19
19
  import {
20
20
  cleanupOldNotifications,
@@ -26,7 +26,7 @@ import {
26
26
  resolveExeSession,
27
27
  sessionScopeFilter,
28
28
  updateTaskStatus
29
- } from "../chunk-OCFYT3LE.js";
29
+ } from "../chunk-LIYHRGAB.js";
30
30
  import "../chunk-LOQCOHEW.js";
31
31
  import "../chunk-TXSJ2L5O.js";
32
32
  import {
@@ -928,7 +928,7 @@ async function boot(options) {
928
928
  };
929
929
  if (nullCount > 0) {
930
930
  try {
931
- const { tryAcquireWorkerSlot, registerWorkerPid } = await import("../worker-gate-NJRW5QYT.js");
931
+ const { tryAcquireWorkerSlot, registerWorkerPid } = await import("../worker-gate-B5MEFZ55.js");
932
932
  if (!tryAcquireWorkerSlot()) {
933
933
  process.stderr.write("[exe-boot] Backfill needed but worker gate full \u2014 skipping\n");
934
934
  } else {
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  fastDbInit
4
- } from "../chunk-PYDL42BL.js";
4
+ } from "../chunk-LJDQQYKZ.js";
5
5
  import {
6
6
  createTaskCore,
7
7
  ensureEmployee,
8
8
  resolveExeSession
9
- } from "../chunk-OCFYT3LE.js";
9
+ } from "../chunk-LIYHRGAB.js";
10
10
  import "../chunk-LOQCOHEW.js";
11
11
  import "../chunk-TXSJ2L5O.js";
12
12
  import "../chunk-64WZEXXA.js";
@@ -19,7 +19,7 @@ import {
19
19
  parseFlags,
20
20
  runAudit,
21
21
  splitAtSentences
22
- } from "../chunk-6F46227N.js";
22
+ } from "../chunk-4Q2OWCEU.js";
23
23
  import "../chunk-L3TB7CC3.js";
24
24
  import "../chunk-6Y4B3QF6.js";
25
25
  import "../chunk-MLKGABMK.js";
@@ -5,10 +5,10 @@ import {
5
5
  import "../chunk-SNN634YS.js";
6
6
  import {
7
7
  fastDbInit
8
- } from "../chunk-PYDL42BL.js";
8
+ } from "../chunk-LJDQQYKZ.js";
9
9
  import {
10
10
  disposeStore
11
- } from "../chunk-RTNRPBQP.js";
11
+ } from "../chunk-CUHCGEHC.js";
12
12
  import "../chunk-LZLXG7TK.js";
13
13
  import "../chunk-MP2AFCGL.js";
14
14
  import "../chunk-EVB53OQD.js";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  fastDbInit
4
- } from "../chunk-PYDL42BL.js";
4
+ } from "../chunk-LJDQQYKZ.js";
5
5
  import {
6
6
  lightweightSearch
7
- } from "../chunk-CGLSVN6N.js";
8
- import "../chunk-RTNRPBQP.js";
7
+ } from "../chunk-YL5UVGMM.js";
8
+ import "../chunk-CUHCGEHC.js";
9
9
  import "../chunk-LZLXG7TK.js";
10
10
  import "../chunk-MP2AFCGL.js";
11
11
  import {
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  BotRegistry,
4
4
  Gateway
5
- } from "../chunk-JFEFVLLD.js";
6
- import "../chunk-IRVLV6C5.js";
7
- import "../chunk-E5PVJXIP.js";
5
+ } from "../chunk-OMS7KJFD.js";
6
+ import "../chunk-P66GZHIS.js";
7
+ import "../chunk-PPGL2TMJ.js";
8
8
  import "../chunk-ONKIWA3R.js";
9
9
  import "../chunk-MP2AFCGL.js";
10
10
  import {
@@ -1058,7 +1058,7 @@ async function main() {
1058
1058
  console.log("[exe-gateway] Generic webhook adapter registered");
1059
1059
  }
1060
1060
  {
1061
- const { createCRMWebhookHandler } = await import("../crm-webhook-DGL6XEOQ.js");
1061
+ const { createCRMWebhookHandler } = await import("../crm-webhook-7OPJC3KJ.js");
1062
1062
  const handler = createCRMWebhookHandler();
1063
1063
  server.onPlatform("crm", handler);
1064
1064
  console.log("[exe-gateway] CRM webhook adapter registered");
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  fastDbInit
4
- } from "../chunk-PYDL42BL.js";
4
+ } from "../chunk-LJDQQYKZ.js";
5
5
  import {
6
6
  isExeSession,
7
7
  listPendingReviews,
8
8
  strictSessionScopeFilter
9
- } from "../chunk-OCFYT3LE.js";
9
+ } from "../chunk-LIYHRGAB.js";
10
10
  import "../chunk-LOQCOHEW.js";
11
11
  import "../chunk-TXSJ2L5O.js";
12
12
  import "../chunk-64WZEXXA.js";
@@ -4,15 +4,15 @@ import {
4
4
  } from "../chunk-V5Y323LO.js";
5
5
  import {
6
6
  fastDbInit
7
- } from "../chunk-PYDL42BL.js";
7
+ } from "../chunk-LJDQQYKZ.js";
8
8
  import {
9
9
  disposeStore,
10
10
  flushBatch
11
- } from "../chunk-RTNRPBQP.js";
11
+ } from "../chunk-CUHCGEHC.js";
12
12
  import "../chunk-LZLXG7TK.js";
13
13
  import {
14
14
  extractRootExe
15
- } from "../chunk-OCFYT3LE.js";
15
+ } from "../chunk-LIYHRGAB.js";
16
16
  import "../chunk-LOQCOHEW.js";
17
17
  import "../chunk-TXSJ2L5O.js";
18
18
  import {
@@ -10,10 +10,10 @@ import "../chunk-INWPOOB6.js";
10
10
  import "../chunk-MWRHXGAB.js";
11
11
  import {
12
12
  fastDbInit
13
- } from "../chunk-PYDL42BL.js";
13
+ } from "../chunk-LJDQQYKZ.js";
14
14
  import {
15
15
  disposeStore
16
- } from "../chunk-RTNRPBQP.js";
16
+ } from "../chunk-CUHCGEHC.js";
17
17
  import "../chunk-LZLXG7TK.js";
18
18
  import {
19
19
  DEFAULT_PROVIDER,