@agentprojectcontext/apx 1.80.2 → 1.89.1
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/package.json +9 -8
- package/skills/apc-context/SKILL.md +14 -7
- package/skills/apx/SKILL.md +62 -2
- package/skills/apx-mcp/SKILL.md +42 -15
- package/src/core/agent/a2a/peers.js +161 -0
- package/src/core/agent/a2a/reply.js +379 -27
- package/src/core/agent/abort.js +25 -0
- package/src/core/agent/agent-model.js +58 -0
- package/src/core/agent/agent-tools.js +101 -0
- package/src/core/agent/author-line.js +110 -0
- package/src/core/agent/build-agent-system.js +52 -18
- package/src/core/agent/channels/voice-context.js +17 -2
- package/src/core/agent/closing-floor.js +117 -0
- package/src/core/agent/constants.js +119 -11
- package/src/core/agent/engine-call.js +56 -0
- package/src/core/agent/group/run-group-turn.js +218 -0
- package/src/core/agent/group/turn-resolver.js +165 -0
- package/src/core/agent/judge.js +138 -11
- package/src/core/agent/loop/side-effects.js +106 -3
- package/src/core/agent/memory.js +31 -18
- package/src/core/agent/model-capabilities.js +47 -0
- package/src/core/agent/model-router.js +11 -40
- package/src/core/agent/prompt-builder.js +47 -0
- package/src/core/agent/prompts/channels/a2a.md +12 -0
- package/src/core/agent/prompts/channels/code.md +3 -1
- package/src/core/agent/prompts/channels/telegram.md +2 -0
- package/src/core/agent/prompts/channels/web_code.md +1 -1
- package/src/core/agent/prompts/channels/whatsapp.md +37 -0
- package/src/core/agent/prompts/core/agent-base.md +2 -0
- package/src/core/agent/prompts/discipline/action.md +1 -0
- package/src/core/agent/prompts/discipline/two-segment.md +2 -1
- package/src/core/agent/prompts/modes/mobility.md +36 -0
- package/src/core/agent/retry.js +42 -0
- package/src/core/agent/run-agent.js +322 -25
- package/src/core/agent/run-turn.js +253 -0
- package/src/core/agent/self-memory.js +18 -52
- package/src/core/agent/skills/agent-skills.js +118 -0
- package/src/core/agent/skills/catalog.js +1 -1
- package/src/core/agent/skills/declared.js +13 -0
- package/src/core/agent/skills/index-store.js +8 -1
- package/src/core/agent/skills/inspector.js +20 -3
- package/src/core/agent/skills/loader.js +18 -3
- package/src/core/agent/skills/media.js +121 -0
- package/src/core/agent/skills/origin.js +61 -0
- package/src/core/agent/skills/sections.js +136 -0
- package/src/core/agent/super-agent.js +54 -14
- package/src/core/agent/tools/handlers/_calendar.js +50 -0
- package/src/core/agent/tools/handlers/add-mcp.js +103 -0
- package/src/core/agent/tools/handlers/asana-create-task.js +3 -1
- package/src/core/agent/tools/handlers/attach-media.js +56 -0
- package/src/core/agent/tools/handlers/calendar-create-event.js +38 -0
- package/src/core/agent/tools/handlers/calendar-find-slot.js +39 -0
- package/src/core/agent/tools/handlers/calendar-list-events.js +39 -0
- package/src/core/agent/tools/handlers/calendar-update-event.js +35 -0
- package/src/core/agent/tools/handlers/call-agent.js +14 -6
- package/src/core/agent/tools/handlers/call-runtime.js +27 -49
- package/src/core/agent/tools/handlers/comment-task.js +78 -0
- package/src/core/agent/tools/handlers/complete-task.js +60 -0
- package/src/core/agent/tools/handlers/configure-agent.js +70 -0
- package/src/core/agent/tools/handlers/create-agent.js +68 -0
- package/src/core/agent/tools/handlers/create-task.js +41 -3
- package/src/core/agent/tools/handlers/import-agent.js +5 -5
- package/src/core/agent/tools/handlers/list-mcp-tools.js +83 -0
- package/src/core/agent/tools/handlers/list-routines.js +46 -0
- package/src/core/agent/tools/handlers/list-tasks.js +8 -1
- package/src/core/agent/tools/handlers/mark-commitment.js +57 -0
- package/src/core/agent/tools/handlers/read-skill.js +64 -0
- package/src/core/agent/tools/handlers/remember-routine.js +2 -8
- package/src/core/agent/tools/handlers/remember.js +82 -6
- package/src/core/agent/tools/handlers/remove-agent.js +42 -0
- package/src/core/agent/tools/handlers/run-routine.js +94 -0
- package/src/core/agent/tools/handlers/run-shell.js +44 -2
- package/src/core/agent/tools/handlers/send-telegram.js +41 -19
- package/src/core/agent/tools/handlers/set-agent-prompt.js +44 -0
- package/src/core/agent/tools/handlers/view-media.js +69 -0
- package/src/core/agent/tools/handlers/write-agent-memory.js +52 -0
- package/src/core/agent/tools/helpers.js +36 -4
- package/src/core/agent/tools/names.js +64 -0
- package/src/core/agent/tools/registry-bridge.js +24 -1
- package/src/core/agent/tools/registry.js +79 -0
- package/src/core/agent/tools/tool-call-parser.js +136 -13
- package/src/core/agent/vision-bridge.js +69 -0
- package/src/core/apc/agent-identity.js +74 -0
- package/src/core/apc/agent-rename-refs.js +187 -0
- package/src/core/apc/agent-write.js +312 -0
- package/src/core/apc/agents-vault.js +1 -1
- package/src/core/apc/blob-keys.js +42 -0
- package/src/core/apc/frontmatter.js +166 -10
- package/src/core/apc/parser.js +33 -83
- package/src/core/apc/paths.js +4 -6
- package/src/core/apc/project-memory.js +44 -0
- package/src/core/apc/projects-helpers.js +33 -0
- package/src/core/apc/scaffold.js +36 -16
- package/src/core/channels/telegram/ask-callbacks.js +103 -0
- package/src/core/channels/telegram/dispatch.js +154 -30
- package/src/core/channels/telegram/helpers.js +59 -7
- package/src/core/channels/telegram/inbound/audio.js +26 -30
- package/src/core/channels/telegram/inbound/file.js +22 -32
- package/src/core/channels/telegram/inbound/photo.js +24 -28
- package/src/core/channels/telegram/progress-gate.js +76 -0
- package/src/core/channels/telegram/reply.js +151 -43
- package/src/core/channels/telegram/voice-note.js +150 -0
- package/src/core/config/index.js +53 -54
- package/src/core/config/paths.js +117 -31
- package/src/core/config/redact.js +89 -4
- package/src/core/config/secret-values.js +2 -4
- package/src/core/constants/actors.js +5 -0
- package/src/core/constants/channels.js +3 -1
- package/src/core/constants/task-categories.js +73 -0
- package/src/core/constants/task-fields.js +28 -0
- package/src/core/engines/_globs.js +33 -0
- package/src/core/engines/anthropic.js +19 -1
- package/src/core/engines/catalog.js +20 -0
- package/src/core/engines/gemini.js +84 -16
- package/src/core/engines/index.js +19 -3
- package/src/core/engines/mock.js +145 -1
- package/src/core/engines/openai-compatible.js +150 -15
- package/src/core/engines/presets.js +36 -9
- package/src/core/engines/zen.js +131 -0
- package/src/core/events/bus.js +140 -0
- package/src/core/events/mascot-notify.js +156 -0
- package/src/core/http-tools/browser.js +366 -36
- package/src/core/http-tools/catalog.js +206 -22
- package/src/core/http-tools/grep.js +62 -7
- package/src/core/http-tools/registry.js +3 -1
- package/src/core/i18n/en.js +34 -3
- package/src/core/i18n/es.js +36 -4
- package/src/core/i18n/index.js +5 -5
- package/src/core/i18n/pt.js +32 -3
- package/src/core/identity/self.js +14 -1
- package/src/core/images/engines/a1111.js +219 -0
- package/src/core/images/engines/index.js +187 -0
- package/src/core/images/engines/mock.js +74 -0
- package/src/core/images/engines/openai.js +130 -0
- package/src/core/images/engines/sdcpp.js +204 -0
- package/src/core/images/engines/shared.js +218 -0
- package/src/core/images/generate.js +260 -0
- package/src/core/integrations/catalog.js +8 -3
- package/src/core/integrations/plugins/_google-oauth.js +179 -0
- package/src/core/integrations/plugins/asana.js +7 -3
- package/src/core/integrations/plugins/calendar.js +404 -0
- package/src/core/integrations/store.js +2 -0
- package/src/core/memory/broker.js +16 -1
- package/src/core/memory/compactor.js +19 -3
- package/src/core/memory/consolidate.js +2 -2
- package/src/core/memory/dated-log.js +66 -0
- package/src/core/memory/embed-engines/custom.js +59 -0
- package/src/core/memory/embed-engines/gemini.js +9 -3
- package/src/core/memory/embed-engines/index.js +87 -15
- package/src/core/memory/embeddings.js +52 -24
- package/src/core/memory/index.js +13 -3
- package/src/core/memory/indexer.js +83 -27
- package/src/core/memory/prune.js +182 -0
- package/src/core/memory/store.js +22 -0
- package/src/core/memory/summarizer.js +72 -8
- package/src/core/mobility/answer.js +80 -0
- package/src/core/mobility/geofence.js +667 -0
- package/src/core/mobility/osm-route.js +282 -0
- package/src/core/mobility/preferences.js +91 -0
- package/src/core/mobility/state.js +245 -0
- package/src/core/mobility/trip-event.js +384 -0
- package/src/core/net/tailscale.js +168 -0
- package/src/core/profiles/bundled/secretary/PROFILE.md +32 -42
- package/src/core/profiles/bundled/secretary/config.schema.es.json +68 -0
- package/src/core/profiles/bundled/secretary/config.schema.json +30 -2
- package/src/core/profiles/bundled/secretary/profile.json +3 -1
- package/src/core/profiles/bundled/secretary/routines/a2a-sweep.json +20 -0
- package/src/core/profiles/bundled/secretary/routines/day-close.json +4 -1
- package/src/core/profiles/bundled/secretary/routines/day-open.json +7 -1
- package/src/core/profiles/bundled/secretary/routines/watch.json +13 -2
- package/src/core/profiles/lifecycle.js +243 -19
- package/src/core/profiles/paths.js +12 -0
- package/src/core/profiles/store.js +47 -0
- package/src/core/routines/active-runs.js +213 -0
- package/src/core/routines/delivery.js +612 -0
- package/src/core/routines/header.js +88 -0
- package/src/core/routines/index.js +26 -0
- package/src/core/routines/run-log.js +78 -0
- package/src/core/routines/runner.js +629 -66
- package/src/core/routines/signals.js +75 -0
- package/src/core/runtime-skills/apc-context/SKILL.md +14 -7
- package/src/core/runtime-skills/apx/SKILL.md +93 -1
- package/src/core/runtime-skills/apx-agency-agents/SKILL.md +2 -2
- package/src/core/runtime-skills/apx-agent/SKILL.md +134 -19
- package/src/core/runtime-skills/apx-commitment/SKILL.md +134 -0
- package/src/core/runtime-skills/apx-image/SKILL.md +60 -0
- package/src/core/runtime-skills/apx-integrations/SKILL.md +82 -0
- package/src/core/runtime-skills/apx-mcp/SKILL.md +45 -14
- package/src/core/runtime-skills/apx-mcp-builder/SKILL.md +4 -4
- package/src/core/runtime-skills/apx-profile/SKILL.md +27 -2
- package/src/core/runtime-skills/apx-project/SKILL.md +23 -2
- package/src/core/runtime-skills/apx-routine/SKILL.md +40 -17
- package/src/core/runtime-skills/apx-runtime/SKILL.md +124 -14
- package/src/core/runtime-skills/apx-sessions/SKILL.md +7 -6
- package/src/core/runtime-skills/apx-skill-builder/SKILL.md +15 -13
- package/src/core/runtime-skills/apx-task/SKILL.md +79 -26
- package/src/core/runtime-skills/apx-telegram/SKILL.md +12 -12
- package/src/core/runtime-skills/apx-transcribe/SKILL.md +56 -0
- package/src/core/runtime-skills/apx-voice/SKILL.md +27 -8
- package/src/core/runtime-skills/claude-code/SKILL.md +8 -0
- package/src/core/runtime-skills/openrouter/SKILL.md +8 -2
- package/src/core/runtimes/_spawn.js +9 -1
- package/src/core/runtimes/claude-code.js +11 -2
- package/src/core/runtimes/codex.js +44 -10
- package/src/core/runtimes/index.js +17 -2
- package/src/core/runtimes/opencode.js +88 -9
- package/src/core/runtimes/outcome.js +119 -0
- package/src/core/sessions/index.js +193 -1
- package/src/core/stores/agent-inbox.js +109 -23
- package/src/core/stores/code-sessions.js +21 -0
- package/src/core/stores/commitments.js +27 -3
- package/src/core/stores/conversations.js +220 -20
- package/src/core/stores/deliveries.js +177 -0
- package/src/core/stores/media-archive.js +228 -0
- package/src/core/stores/messages.js +1096 -112
- package/src/core/stores/organization.js +34 -0
- package/src/core/stores/project-memory.js +71 -0
- package/src/core/stores/routine-memory.js +16 -8
- package/src/core/stores/routines.js +27 -49
- package/src/core/stores/sessions.js +4 -8
- package/src/core/stores/tasks.js +212 -18
- package/src/core/stores/turn-record.js +209 -0
- package/src/core/tasks/columns.js +136 -0
- package/src/core/tasks/comment-turn.js +258 -0
- package/src/core/util/time.js +13 -0
- package/src/core/voice/engines/index.js +54 -1
- package/src/core/voice/engines/openai.js +50 -4
- package/src/core/voice/opus.js +67 -0
- package/src/core/voice/pronounceable.js +43 -0
- package/src/core/voice/transcription.js +4 -0
- package/src/core/voice/tts.js +114 -24
- package/src/host/daemon/active-turns.js +188 -0
- package/src/host/daemon/api/admin-config.js +9 -0
- package/src/host/daemon/api/agents.js +99 -90
- package/src/host/daemon/api/artifact-preview.js +7 -6
- package/src/host/daemon/api/artifacts.js +3 -2
- package/src/host/daemon/api/code.js +55 -9
- package/src/host/daemon/api/commitments.js +11 -0
- package/src/host/daemon/api/confirm.js +3 -2
- package/src/host/daemon/api/conversations.js +543 -35
- package/src/host/daemon/api/deck.js +9 -8
- package/src/host/daemon/api/deliveries.js +33 -0
- package/src/host/daemon/api/desktop.js +5 -4
- package/src/host/daemon/api/embeddings.js +15 -6
- package/src/host/daemon/api/engines.js +59 -8
- package/src/host/daemon/api/exec.js +437 -121
- package/src/host/daemon/api/groups.js +215 -0
- package/src/host/daemon/api/images.js +107 -0
- package/src/host/daemon/api/inbox.js +123 -2
- package/src/host/daemon/api/integrations.js +64 -2
- package/src/host/daemon/api/mcps.js +7 -6
- package/src/host/daemon/api/media.js +283 -0
- package/src/host/daemon/api/mobility.js +177 -0
- package/src/host/daemon/api/net.js +182 -0
- package/src/host/daemon/api/pairing.js +38 -5
- package/src/host/daemon/api/profiles.js +30 -2
- package/src/host/daemon/api/routines.js +36 -4
- package/src/host/daemon/api/runtimes.js +74 -39
- package/src/host/daemon/api/sessions-search.js +7 -2
- package/src/host/daemon/api/sessions.js +44 -2
- package/src/host/daemon/api/shared.js +127 -20
- package/src/host/daemon/api/skills.js +11 -4
- package/src/host/daemon/api/super-agent.js +384 -53
- package/src/host/daemon/api/tasks.js +180 -10
- package/src/host/daemon/api/telegram.js +11 -10
- package/src/host/daemon/api/thread-faces.js +159 -0
- package/src/host/daemon/api/top-level.js +3 -3
- package/src/host/daemon/api/transcribe.js +11 -10
- package/src/host/daemon/api/tts.js +97 -4
- package/src/host/daemon/api/turn-abort.js +23 -0
- package/src/host/daemon/api/turns.js +49 -0
- package/src/host/daemon/api/voice.js +5 -4
- package/src/host/daemon/api/web.js +98 -0
- package/src/host/daemon/api.js +39 -0
- package/src/host/daemon/delivery-sweep.js +58 -0
- package/src/host/daemon/desktop-ws.js +5 -23
- package/src/host/daemon/events-ws.js +273 -0
- package/src/host/daemon/index.js +59 -15
- package/src/host/daemon/plugins/desktop/index.js +17 -4
- package/src/host/daemon/plugins/telegram/index.js +78 -40
- package/src/host/daemon/pty-bridge.py +99 -0
- package/src/host/daemon/routines-scheduler.js +1 -0
- package/src/host/daemon/smoke.js +1 -2
- package/src/host/daemon/terminal-ws.js +132 -0
- package/src/host/daemon/tts-keepwarm.js +87 -0
- package/src/host/daemon/wakeup.js +11 -6
- package/src/host/daemon/whisper-server.js +44 -0
- package/src/host/daemon/whisper-server.py +70 -13
- package/src/host/daemon/ws-auth.js +28 -0
- package/src/interfaces/android/app/build.gradle +42 -0
- package/src/interfaces/android/app/proguard-rules.pro +4 -0
- package/src/interfaces/android/app/src/main/AndroidManifest.xml +139 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AlertScreen.java +139 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AndroidAutoDetector.java +106 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxCarAppService.java +57 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxPreferences.java +165 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarAlertStore.java +84 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageActionReceiver.java +47 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageNotification.java +152 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonAddress.java +35 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonClient.java +339 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DeviceLocation.java +38 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ErrandScreen.java +127 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MainActivity.java +872 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationDetector.java +63 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationListenerService.java +453 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsShareIntentParser.java +93 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotBlobCatalog.java +66 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotOverlayService.java +448 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotView.java +249 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MessageFrameParser.java +240 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/NotifyChannels.java +69 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityActionReceiver.java +78 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityNotification.java +161 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/StartupReceiver.java +57 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelEventGate.java +62 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelStatusBanner.java +116 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripLocationService.java +272 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripPlacesSheet.java +203 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripScreen.java +182 -0
- package/src/interfaces/android/app/src/main/res/drawable/app_background.xml +12 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_app.xml +10 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_launcher_foreground.xml +12 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_notification.xml +22 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_trip_car.xml +37 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/apx_logo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_amatista.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_aqua.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_brasa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_campana.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_caracol.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_carbon.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cobalto.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cometa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_coral.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cubi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_eclipse.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_faro.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_gajo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_iris.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_kiwi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_laguna.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_lila.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_menta.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_nimbo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_noche.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_onyx.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_orbita.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_ovni.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_papa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_parche.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_peon.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_perla.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_pino.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_quad.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_rubi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_saturno.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trebol.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trino.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_volcan.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_zafiro.png +0 -0
- package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
- package/src/interfaces/android/app/src/main/res/raw/apx_notification.mp3 +0 -0
- package/src/interfaces/android/app/src/main/res/values/colors.xml +4 -0
- package/src/interfaces/android/app/src/main/res/values/strings.xml +25 -0
- package/src/interfaces/android/app/src/main/res/values/styles.xml +10 -0
- package/src/interfaces/android/app/src/main/res/values-v31/styles.xml +14 -0
- package/src/interfaces/android/app/src/main/res/xml/automotive_app_desc.xml +9 -0
- package/src/interfaces/android/app/src/main/res/xml/network_security_config.xml +10 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/AndroidAutoDetectorTest.java +85 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/CarAlertStoreTest.java +104 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/DaemonAddressTest.java +23 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsNavigationDetectorTest.java +69 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsShareIntentParserTest.java +31 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MessageFrameParserTest.java +180 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TravelEventGateTest.java +64 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TripPlacesSheetTest.java +66 -0
- package/src/interfaces/android/build.gradle +3 -0
- package/src/interfaces/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/src/interfaces/android/gradle/wrapper/gradle-wrapper.properties +9 -0
- package/src/interfaces/android/gradle.properties +3 -0
- package/src/interfaces/android/gradlew +248 -0
- package/src/interfaces/android/gradlew.bat +82 -0
- package/src/interfaces/android/settings.gradle +18 -0
- package/src/interfaces/cli/commands/a2a.js +145 -4
- package/src/interfaces/cli/commands/agent.js +247 -22
- package/src/interfaces/cli/commands/code.js +1 -1
- package/src/interfaces/cli/commands/commitment.js +5 -0
- package/src/interfaces/cli/commands/config.js +85 -6
- package/src/interfaces/cli/commands/exec.js +90 -1
- package/src/interfaces/cli/commands/image.js +314 -0
- package/src/interfaces/cli/commands/mcp.js +87 -23
- package/src/interfaces/cli/commands/memory.js +35 -22
- package/src/interfaces/cli/commands/panel.js +94 -0
- package/src/interfaces/cli/commands/profile.js +14 -0
- package/src/interfaces/cli/commands/project.js +29 -0
- package/src/interfaces/cli/commands/routine.js +45 -10
- package/src/interfaces/cli/commands/runtime.js +30 -7
- package/src/interfaces/cli/commands/session.js +90 -38
- package/src/interfaces/cli/commands/sessions.js +35 -2
- package/src/interfaces/cli/commands/skills.js +15 -9
- package/src/interfaces/cli/commands/status.js +2 -3
- package/src/interfaces/cli/commands/task.js +54 -5
- package/src/interfaces/cli/commands/telegram.js +12 -4
- package/src/interfaces/cli/commands/transcribe.js +177 -0
- package/src/interfaces/cli/help/index.js +311 -72
- package/src/interfaces/cli/http.js +61 -13
- package/src/interfaces/cli/index.js +1 -1
- package/src/interfaces/cli/routes/agent.js +5 -4
- package/src/interfaces/cli/routes/commitment.js +3 -2
- package/src/interfaces/cli/routes/config.js +7 -2
- package/src/interfaces/cli/routes/image.js +11 -0
- package/src/interfaces/cli/routes/index.js +2 -0
- package/src/interfaces/cli/routes/log.js +1 -1
- package/src/interfaces/cli/routes/memory.js +3 -2
- package/src/interfaces/cli/routes/panel.js +15 -2
- package/src/interfaces/cli/routes/profile.js +3 -2
- package/src/interfaces/cli/routes/transcribe.js +10 -0
- package/src/interfaces/cli/stdin.js +29 -0
- package/src/interfaces/desktop/assets/blobs/amatista.png +0 -0
- package/src/interfaces/desktop/assets/blobs/aqua.png +0 -0
- package/src/interfaces/desktop/assets/blobs/brasa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/campana.png +0 -0
- package/src/interfaces/desktop/assets/blobs/caracol.png +0 -0
- package/src/interfaces/desktop/assets/blobs/carbon.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cobalto.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cometa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/coral.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cubi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/eclipse.png +0 -0
- package/src/interfaces/desktop/assets/blobs/faro.png +0 -0
- package/src/interfaces/desktop/assets/blobs/gajo.png +0 -0
- package/src/interfaces/desktop/assets/blobs/iris.png +0 -0
- package/src/interfaces/desktop/assets/blobs/kiwi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/laguna.png +0 -0
- package/src/interfaces/desktop/assets/blobs/lila.png +0 -0
- package/src/interfaces/desktop/assets/blobs/menta.png +0 -0
- package/src/interfaces/desktop/assets/blobs/nimbo.png +0 -0
- package/src/interfaces/desktop/assets/blobs/noche.png +0 -0
- package/src/interfaces/desktop/assets/blobs/onyx.png +0 -0
- package/src/interfaces/desktop/assets/blobs/orbita.png +0 -0
- package/src/interfaces/desktop/assets/blobs/ovni.png +0 -0
- package/src/interfaces/desktop/assets/blobs/papa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/parche.png +0 -0
- package/src/interfaces/desktop/assets/blobs/peon.png +0 -0
- package/src/interfaces/desktop/assets/blobs/perla.png +0 -0
- package/src/interfaces/desktop/assets/blobs/pino.png +0 -0
- package/src/interfaces/desktop/assets/blobs/quad.png +0 -0
- package/src/interfaces/desktop/assets/blobs/rubi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/saturno.png +0 -0
- package/src/interfaces/desktop/assets/blobs/trebol.png +0 -0
- package/src/interfaces/desktop/assets/blobs/trino.png +0 -0
- package/src/interfaces/desktop/assets/blobs/volcan.png +0 -0
- package/src/interfaces/desktop/assets/blobs/zafiro.png +0 -0
- package/src/interfaces/desktop/assets/notification.mp3 +0 -0
- package/src/interfaces/desktop/main.js +473 -29
- package/src/interfaces/desktop/mascot-blobs.js +41 -0
- package/src/interfaces/desktop/mascot-preload.js +32 -0
- package/src/interfaces/desktop/mascot.css +186 -0
- package/src/interfaces/desktop/mascot.html +40 -0
- package/src/interfaces/desktop/mascot.js +163 -0
- package/src/interfaces/desktop/preload.js +10 -0
- package/src/interfaces/desktop/renderer.js +308 -48
- package/src/interfaces/desktop/style.css +34 -0
- package/src/interfaces/mcp-server/index.js +87 -0
- package/src/interfaces/tui/_shims/util-locale.ts +0 -2
- package/src/interfaces/tui/app.tsx +0 -6
- package/src/interfaces/tui/attach.ts +0 -1
- package/src/interfaces/tui/context/sdk-apx.tsx +0 -4
- package/src/interfaces/tui/plugin/api.tsx +0 -3
- package/src/interfaces/tui/plugin/runtime.ts +0 -3
- package/src/interfaces/tui/thread.ts +0 -16
- package/src/interfaces/web/README.md +22 -14
- package/src/interfaces/web/dist/assets/claude-XtpLmGtF.webp +0 -0
- package/src/interfaces/web/dist/assets/codex-DExPUgvh.webp +0 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css +32 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.br +0 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.gz +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js +1074 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.br +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.gz +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map +1 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.br +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.gz +0 -0
- package/src/interfaces/web/dist/favicon/dark/site.webmanifest +12 -6
- package/src/interfaces/web/dist/favicon/white/site.webmanifest +12 -6
- package/src/interfaces/web/dist/index.html +22 -6
- package/src/interfaces/web/dist/index.html.br +0 -0
- package/src/interfaces/web/dist/index.html.gz +0 -0
- package/src/interfaces/web/dist/manifest.webmanifest +25 -0
- package/src/interfaces/web/dist/modules/blobs/amatista.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/aqua.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/brasa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/campana.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/caracol.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/carbon.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cobalto.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cometa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/coral.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cubi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/eclipse.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/faro.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/gajo.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/iris.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/kiwi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/laguna.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/lila.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/menta.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/nimbo.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/noche.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/onyx.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/orbita.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/ovni.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/papa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/parche.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/peon.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/perla.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/pino.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/quad.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/rubi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/saturno.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/trebol.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/trino.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/volcan.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/zafiro.png +0 -0
- package/src/interfaces/web/dist/sw.js +106 -0
- package/src/interfaces/web/dist/sw.js.br +0 -0
- package/src/interfaces/web/dist/sw.js.gz +0 -0
- package/src/interfaces/web/eslint.config.js +83 -0
- package/src/interfaces/web/index.html +20 -4
- package/src/interfaces/web/package-lock.json +1651 -1280
- package/src/interfaces/web/package.json +9 -10
- package/src/interfaces/web/pnpm-lock.yaml +867 -869
- package/src/interfaces/web/public/favicon/dark/site.webmanifest +12 -6
- package/src/interfaces/web/public/favicon/white/site.webmanifest +12 -6
- package/src/interfaces/web/public/manifest.webmanifest +25 -0
- package/src/interfaces/web/public/modules/blobs/amatista.png +0 -0
- package/src/interfaces/web/public/modules/blobs/aqua.png +0 -0
- package/src/interfaces/web/public/modules/blobs/brasa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/campana.png +0 -0
- package/src/interfaces/web/public/modules/blobs/caracol.png +0 -0
- package/src/interfaces/web/public/modules/blobs/carbon.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cobalto.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cometa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/coral.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cubi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/eclipse.png +0 -0
- package/src/interfaces/web/public/modules/blobs/faro.png +0 -0
- package/src/interfaces/web/public/modules/blobs/gajo.png +0 -0
- package/src/interfaces/web/public/modules/blobs/iris.png +0 -0
- package/src/interfaces/web/public/modules/blobs/kiwi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/laguna.png +0 -0
- package/src/interfaces/web/public/modules/blobs/lila.png +0 -0
- package/src/interfaces/web/public/modules/blobs/menta.png +0 -0
- package/src/interfaces/web/public/modules/blobs/nimbo.png +0 -0
- package/src/interfaces/web/public/modules/blobs/noche.png +0 -0
- package/src/interfaces/web/public/modules/blobs/onyx.png +0 -0
- package/src/interfaces/web/public/modules/blobs/orbita.png +0 -0
- package/src/interfaces/web/public/modules/blobs/ovni.png +0 -0
- package/src/interfaces/web/public/modules/blobs/papa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/parche.png +0 -0
- package/src/interfaces/web/public/modules/blobs/peon.png +0 -0
- package/src/interfaces/web/public/modules/blobs/perla.png +0 -0
- package/src/interfaces/web/public/modules/blobs/pino.png +0 -0
- package/src/interfaces/web/public/modules/blobs/quad.png +0 -0
- package/src/interfaces/web/public/modules/blobs/rubi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/saturno.png +0 -0
- package/src/interfaces/web/public/modules/blobs/trebol.png +0 -0
- package/src/interfaces/web/public/modules/blobs/trino.png +0 -0
- package/src/interfaces/web/public/modules/blobs/volcan.png +0 -0
- package/src/interfaces/web/public/modules/blobs/zafiro.png +0 -0
- package/src/interfaces/web/public/sw.js +106 -0
- package/src/interfaces/web/src/App.tsx +106 -10
- package/src/interfaces/web/src/assets/cli/claude.webp +0 -0
- package/src/interfaces/web/src/assets/cli/codex.webp +0 -0
- package/src/interfaces/web/src/assets/cli/cursor.svg +1 -0
- package/src/interfaces/web/src/assets/cli/opencode.png +0 -0
- package/src/interfaces/web/src/components/Combobox.tsx +201 -0
- package/src/interfaces/web/src/components/MobileHint.tsx +95 -0
- package/src/interfaces/web/src/components/MobileLinkDialog.tsx +156 -0
- package/src/interfaces/web/src/components/ModelCombobox.tsx +21 -113
- package/src/interfaces/web/src/components/{routines/ReadOnlyBlock.tsx → ReadOnlyBlock.tsx} +13 -4
- package/src/interfaces/web/src/components/Roby.tsx +5 -3
- package/src/interfaces/web/src/components/RobyBubble.tsx +23 -5
- package/src/interfaces/web/src/components/RowMenu.tsx +46 -0
- package/src/interfaces/web/src/components/TimezoneSelect.tsx +4 -1
- package/src/interfaces/web/src/components/Toast.tsx +50 -14
- package/src/interfaces/web/src/components/UiSelect.tsx +12 -5
- package/src/interfaces/web/src/components/agents/AgentAvatar.tsx +171 -0
- package/src/interfaces/web/src/components/agents/AgentFormFields.tsx +42 -11
- package/src/interfaces/web/src/components/agents/AgentModelBadge.tsx +157 -0
- package/src/interfaces/web/src/components/agents/AgentModelSelect.tsx +57 -0
- package/src/interfaces/web/src/components/agents/AgentSkillsPicker.tsx +115 -0
- package/src/interfaces/web/src/components/agents/BlobAvatar.tsx +50 -0
- package/src/interfaces/web/src/components/agents/blobPresets.ts +50 -0
- package/src/interfaces/web/src/components/agents/modelCatalog.ts +66 -0
- package/src/interfaces/web/src/components/chat/ActionGroup.tsx +162 -0
- package/src/interfaces/web/src/components/chat/AskAnswersCard.tsx +4 -3
- package/src/interfaces/web/src/components/chat/AskQuestionsCard.tsx +1 -1
- package/src/interfaces/web/src/components/chat/Attachment.tsx +220 -0
- package/src/interfaces/web/src/components/chat/ChatList.tsx +226 -51
- package/src/interfaces/web/src/components/chat/ChatRowActivity.tsx +45 -0
- package/src/interfaces/web/src/components/chat/Composer.tsx +672 -23
- package/src/interfaces/web/src/components/chat/ComposerCommands.tsx +175 -0
- package/src/interfaces/web/src/components/chat/ComposerSuggest.tsx +215 -0
- package/src/interfaces/web/src/components/chat/ContextBar.tsx +133 -65
- package/src/interfaces/web/src/components/chat/InlineAskPanel.tsx +107 -47
- package/src/interfaces/web/src/components/chat/MessageBubble.tsx +460 -119
- package/src/interfaces/web/src/components/chat/MessageList.tsx +165 -18
- package/src/interfaces/web/src/components/chat/ReasoningBlock.tsx +58 -0
- package/src/interfaces/web/src/components/chat/SessionPicker.tsx +182 -0
- package/src/interfaces/web/src/components/chat/SkillTrace.tsx +183 -0
- package/src/interfaces/web/src/components/chat/ToolCall.tsx +11 -11
- package/src/interfaces/web/src/components/code/CodeContextTab.tsx +87 -53
- package/src/interfaces/web/src/components/code/CodeFileTree.tsx +11 -52
- package/src/interfaces/web/src/components/code/CodeFileViewer.tsx +5 -4
- package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +31 -7
- package/src/interfaces/web/src/components/code/CodeSessionList.tsx +32 -11
- package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +33 -3
- package/src/interfaces/web/src/components/code/CodeTerminal.tsx +5 -4
- package/src/interfaces/web/src/components/code/NewCodeSessionDialog.tsx +164 -0
- package/src/interfaces/web/src/components/commitments/CommitmentDetail.tsx +162 -0
- package/src/interfaces/web/src/components/commitments/CommitmentFormDialog.tsx +158 -0
- package/src/interfaces/web/src/components/commitments/CommitmentList.tsx +194 -0
- package/src/interfaces/web/src/components/commitments/commitmentState.tsx +46 -0
- package/src/interfaces/web/src/components/common/BulkActionBar.tsx +60 -0
- package/src/interfaces/web/src/components/common/ConfirmDialog.tsx +4 -1
- package/src/interfaces/web/src/components/common/SelectCheckbox.tsx +40 -0
- package/src/interfaces/web/src/components/common/TabNav.tsx +1 -1
- package/src/interfaces/web/src/components/cron/CronPicker.tsx +1 -1
- package/src/interfaces/web/src/components/files/FileBrowser.tsx +1 -1
- package/src/interfaces/web/src/components/files/FileTree.tsx +6 -4
- package/src/interfaces/web/src/components/files/FileViewer.tsx +9 -5
- package/src/interfaces/web/src/components/files/MarkdownPreview.tsx +45 -9
- package/src/interfaces/web/src/components/images/ImageDefaultsCard.tsx +93 -0
- package/src/interfaces/web/src/components/images/ImageProviderList.tsx +142 -0
- package/src/interfaces/web/src/components/images/ImageProviderModal.tsx +263 -0
- package/src/interfaces/web/src/components/images/ImageTestCard.tsx +142 -0
- package/src/interfaces/web/src/components/inbox/ChannelFilter.tsx +178 -0
- package/src/interfaces/web/src/components/inbox/InboxList.tsx +77 -81
- package/src/interfaces/web/src/components/inbox/InboxRowItem.tsx +140 -0
- package/src/interfaces/web/src/components/integrations/ComingSoonPlugin.tsx +2 -2
- package/src/interfaces/web/src/components/integrations/PluginConnect.tsx +208 -30
- package/src/interfaces/web/src/components/integrations/PluginToolsSection.tsx +1 -1
- package/src/interfaces/web/src/components/layout/ProjectAvatar.tsx +39 -24
- package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +253 -58
- package/src/interfaces/web/src/components/memory/MemoryBrowser.tsx +94 -47
- package/src/interfaces/web/src/components/routines/ExecutionsList.tsx +202 -90
- package/src/interfaces/web/src/components/routines/RoutineDetail.tsx +28 -6
- package/src/interfaces/web/src/components/routines/RoutineEditor.tsx +16 -5
- package/src/interfaces/web/src/components/routines/RoutineList.tsx +49 -9
- package/src/interfaces/web/src/components/routines/VarTextarea.tsx +1 -1
- package/src/interfaces/web/src/components/routines/runChat.ts +121 -0
- package/src/interfaces/web/src/components/sessions/SessionDetail.tsx +148 -0
- package/src/interfaces/web/src/components/sessions/SessionTerminal.tsx +98 -0
- package/src/interfaces/web/src/components/settings/AccessPanel.tsx +205 -0
- package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +246 -101
- package/src/interfaces/web/src/components/settings/DesktopSettingsPanel.tsx +36 -2
- package/src/interfaces/web/src/components/settings/DevicesPanel.tsx +19 -6
- package/src/interfaces/web/src/components/settings/EmbedProviderList.tsx +274 -0
- package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +26 -6
- package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +118 -119
- package/src/interfaces/web/src/components/settings/NudgePanel.tsx +4 -3
- package/src/interfaces/web/src/components/settings/PairDeviceDialog.tsx +15 -4
- package/src/interfaces/web/src/components/settings/PanelPrefs.tsx +374 -0
- package/src/interfaces/web/src/components/settings/ProfilePanel.tsx +70 -2
- package/src/interfaces/web/src/components/settings/RoutingPanel.tsx +2 -1
- package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +102 -43
- package/src/interfaces/web/src/components/settings/SkillsManager.tsx +76 -21
- package/src/interfaces/web/src/components/settings/SkillsSettings.tsx +10 -3
- package/src/interfaces/web/src/components/settings/SuperAgentPanel.tsx +8 -0
- package/src/interfaces/web/src/components/settings/TelegramChannelsPanel.tsx +11 -2
- package/src/interfaces/web/src/components/settings/TelegramContactsPanel.tsx +19 -8
- package/src/interfaces/web/src/components/settings/TelegramRolesPanel.tsx +12 -2
- package/src/interfaces/web/src/components/settings/WebPanel.tsx +22 -31
- package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +15 -3
- package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +97 -66
- package/src/interfaces/web/src/components/settings/providers/ProviderTestDialog.tsx +150 -0
- package/src/interfaces/web/src/components/settings/providers/typeStyles.ts +67 -25
- package/src/interfaces/web/src/components/settings/providers/types.ts +3 -0
- package/src/interfaces/web/src/components/tasks/TaskBoard.tsx +201 -0
- package/src/interfaces/web/src/components/tasks/TaskColumnsDialog.tsx +243 -0
- package/src/interfaces/web/src/components/tasks/TaskComments.tsx +167 -0
- package/src/interfaces/web/src/components/tasks/TaskDetail.tsx +335 -0
- package/src/interfaces/web/src/components/tasks/TaskFormDialog.tsx +406 -0
- package/src/interfaces/web/src/components/tasks/TaskList.tsx +258 -0
- package/src/interfaces/web/src/components/tasks/TaskSubtasks.tsx +126 -0
- package/src/interfaces/web/src/components/tasks/columns.ts +51 -0
- package/src/interfaces/web/src/components/tasks/taskStatus.tsx +159 -34
- package/src/interfaces/web/src/components/tasks/taskViewPrefs.ts +73 -0
- package/src/interfaces/web/src/components/tasks/useTaskColumns.ts +31 -0
- package/src/interfaces/web/src/components/ui/chat-input.tsx +136 -12
- package/src/interfaces/web/src/components/ui/context-menu.tsx +15 -198
- package/src/interfaces/web/src/components/ui/dialog.tsx +3 -2
- package/src/interfaces/web/src/components/ui/filter-chips.tsx +4 -0
- package/src/interfaces/web/src/components/ui/popover.tsx +14 -49
- package/src/interfaces/web/src/components/ui/sheet.tsx +2 -1
- package/src/interfaces/web/src/components/ui/spinner.tsx +2 -1
- package/src/interfaces/web/src/components/ui.tsx +62 -23
- package/src/interfaces/web/src/components/voice/VoiceProviderList.tsx +2 -1
- package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +66 -8
- package/src/interfaces/web/src/components/voice/VoiceQvoxInstallCard.tsx +63 -0
- package/src/interfaces/web/src/components/voice/VoiceQvoxStatusCard.tsx +51 -0
- package/src/interfaces/web/src/components/voice/VoiceSttCard.tsx +4 -3
- package/src/interfaces/web/src/components/voice/VoiceTestCard.tsx +38 -4
- package/src/interfaces/web/src/constants/index.ts +1 -0
- package/src/interfaces/web/src/hooks/useChannelPrefs.ts +39 -0
- package/src/interfaces/web/src/hooks/useChat.ts +1092 -85
- package/src/interfaces/web/src/hooks/useChatActivity.ts +24 -0
- package/src/interfaces/web/src/hooks/useInbox.ts +26 -4
- package/src/interfaces/web/src/hooks/useLiveMessages.ts +16 -0
- package/src/interfaces/web/src/hooks/useOllamaModels.ts +79 -0
- package/src/interfaces/web/src/hooks/useRecorder.ts +198 -0
- package/src/interfaces/web/src/hooks/useTokenBootstrap.ts +23 -6
- package/src/interfaces/web/src/i18n/en.ts +832 -175
- package/src/interfaces/web/src/i18n/es.ts +841 -188
- package/src/interfaces/web/src/lib/api/agents.ts +23 -4
- package/src/interfaces/web/src/lib/api/code.ts +17 -0
- package/src/interfaces/web/src/lib/api/commitments.ts +7 -1
- package/src/interfaces/web/src/lib/api/conversations.ts +38 -11
- package/src/interfaces/web/src/lib/api/embeddings.ts +3 -0
- package/src/interfaces/web/src/lib/api/engines.ts +14 -0
- package/src/interfaces/web/src/lib/api/groups.ts +93 -0
- package/src/interfaces/web/src/lib/api/images.ts +193 -0
- package/src/interfaces/web/src/lib/api/inbox.ts +29 -5
- package/src/interfaces/web/src/lib/api/integrations.ts +9 -0
- package/src/interfaces/web/src/lib/api/media.ts +126 -0
- package/src/interfaces/web/src/lib/api/net.ts +44 -0
- package/src/interfaces/web/src/lib/api/profiles.ts +12 -0
- package/src/interfaces/web/src/lib/api/projects.ts +9 -1
- package/src/interfaces/web/src/lib/api/routines.ts +9 -1
- package/src/interfaces/web/src/lib/api/sessions.ts +18 -0
- package/src/interfaces/web/src/lib/api/skills.ts +8 -0
- package/src/interfaces/web/src/lib/api/super_agent.ts +3 -0
- package/src/interfaces/web/src/lib/api/tasks.ts +46 -6
- package/src/interfaces/web/src/lib/api/tools.ts +2 -0
- package/src/interfaces/web/src/lib/api/transcribe.ts +31 -0
- package/src/interfaces/web/src/lib/api/turns.ts +20 -0
- package/src/interfaces/web/src/lib/api/voice.ts +72 -2
- package/src/interfaces/web/src/lib/api.ts +3 -0
- package/src/interfaces/web/src/lib/channels.ts +214 -0
- package/src/interfaces/web/src/lib/chat-activity.ts +175 -0
- package/src/interfaces/web/src/lib/chat-prefs.ts +48 -0
- package/src/interfaces/web/src/lib/code-context.ts +0 -2
- package/src/interfaces/web/src/lib/http.ts +51 -17
- package/src/interfaces/web/src/lib/inbox-selection.ts +29 -0
- package/src/interfaces/web/src/lib/live.ts +252 -0
- package/src/interfaces/web/src/lib/net.ts +211 -0
- package/src/interfaces/web/src/lib/notify.ts +331 -0
- package/src/interfaces/web/src/lib/projectNav.ts +40 -0
- package/src/interfaces/web/src/lib/pwa.ts +115 -0
- package/src/interfaces/web/src/lib/qvox.ts +24 -0
- package/src/interfaces/web/src/lib/slug.ts +3 -0
- package/src/interfaces/web/src/lib/tone.ts +150 -0
- package/src/interfaces/web/src/main.tsx +15 -4
- package/src/interfaces/web/src/screens/ApxAdminScreen.tsx +33 -11
- package/src/interfaces/web/src/screens/InboxScreen.tsx +126 -71
- package/src/interfaces/web/src/screens/ProjectScreen.tsx +8 -4
- package/src/interfaces/web/src/screens/SettingsScreen.tsx +7 -4
- package/src/interfaces/web/src/screens/base/AgentDefaultsTab.tsx +30 -9
- package/src/interfaces/web/src/screens/base/CommitmentsTab.tsx +150 -168
- package/src/interfaces/web/src/screens/base/LogsTab.tsx +8 -7
- package/src/interfaces/web/src/screens/base/SessionsTab.tsx +99 -37
- package/src/interfaces/web/src/screens/base/WorkspacesTab.tsx +1 -1
- package/src/interfaces/web/src/screens/mobile/MobileChat.tsx +85 -0
- package/src/interfaces/web/src/screens/mobile/MobileChatList.tsx +244 -0
- package/src/interfaces/web/src/screens/mobile/MobileCommitments.tsx +350 -0
- package/src/interfaces/web/src/screens/mobile/MobileScreen.tsx +138 -0
- package/src/interfaces/web/src/screens/mobile/MobileTabBar.tsx +105 -0
- package/src/interfaces/web/src/screens/mobile/MobileTasks.tsx +407 -0
- package/src/interfaces/web/src/screens/mobile/NewChatSheet.tsx +313 -0
- package/src/interfaces/web/src/screens/mobile/mobileList.tsx +194 -0
- package/src/interfaces/web/src/screens/mobile/routes.ts +239 -0
- package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +135 -64
- package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +0 -1
- package/src/interfaces/web/src/screens/modules/ImagesScreen.tsx +172 -0
- package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +36 -4
- package/src/interfaces/web/src/screens/project/AgentBrainGraph.tsx +117 -30
- package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +537 -92
- package/src/interfaces/web/src/screens/project/AgentsTab.tsx +344 -93
- package/src/interfaces/web/src/screens/project/ArtifactsTab.tsx +1 -1
- package/src/interfaces/web/src/screens/project/ChatTab.tsx +1160 -94
- package/src/interfaces/web/src/screens/project/IntegrationsTab.tsx +3 -2
- package/src/interfaces/web/src/screens/project/McpsTab.tsx +62 -14
- package/src/interfaces/web/src/screens/project/Overview.tsx +36 -15
- package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +93 -8
- package/src/interfaces/web/src/screens/project/SkillsTab.tsx +4 -1
- package/src/interfaces/web/src/screens/project/StructureTab.tsx +5 -4
- package/src/interfaces/web/src/screens/project/TasksTab.tsx +351 -129
- package/src/interfaces/web/src/screens/project/VarsTab.tsx +17 -5
- package/src/interfaces/web/src/styles.css +106 -31
- package/src/interfaces/web/src/types/daemon.ts +246 -2
- package/src/interfaces/web/src/vite-env.d.ts +20 -0
- package/src/interfaces/tui/plugin/command-shim.ts +0 -109
- package/src/interfaces/web/components.json +0 -25
- package/src/interfaces/web/dist/assets/index-CvEoGtTf.js +0 -849
- package/src/interfaces/web/dist/assets/index-CvEoGtTf.js.map +0 -1
- package/src/interfaces/web/dist/assets/index-DzBBXFaO.css +0 -1
- package/src/interfaces/web/src/components/tasks/TaskDetailPanel.tsx +0 -142
- package/src/interfaces/web/src/components/ui/accordion.tsx +0 -72
- package/src/interfaces/web/src/components/ui/alert-dialog.tsx +0 -187
- package/src/interfaces/web/src/components/ui/alert.tsx +0 -76
- package/src/interfaces/web/src/components/ui/aspect-ratio.tsx +0 -22
- package/src/interfaces/web/src/components/ui/avatar.tsx +0 -107
- package/src/interfaces/web/src/components/ui/breadcrumb.tsx +0 -125
- package/src/interfaces/web/src/components/ui/button-group.tsx +0 -87
- package/src/interfaces/web/src/components/ui/calendar.tsx +0 -221
- package/src/interfaces/web/src/components/ui/card.tsx +0 -103
- package/src/interfaces/web/src/components/ui/carousel.tsx +0 -242
- package/src/interfaces/web/src/components/ui/chart.tsx +0 -371
- package/src/interfaces/web/src/components/ui/checkbox.tsx +0 -29
- package/src/interfaces/web/src/components/ui/collapsible.tsx +0 -19
- package/src/interfaces/web/src/components/ui/combobox.tsx +0 -295
- package/src/interfaces/web/src/components/ui/command.tsx +0 -196
- package/src/interfaces/web/src/components/ui/direction.tsx +0 -4
- package/src/interfaces/web/src/components/ui/drawer.tsx +0 -134
- package/src/interfaces/web/src/components/ui/empty.tsx +0 -104
- package/src/interfaces/web/src/components/ui/field.tsx +0 -236
- package/src/interfaces/web/src/components/ui/hover-card.tsx +0 -51
- package/src/interfaces/web/src/components/ui/input-otp.tsx +0 -85
- package/src/interfaces/web/src/components/ui/item.tsx +0 -201
- package/src/interfaces/web/src/components/ui/menubar.tsx +0 -280
- package/src/interfaces/web/src/components/ui/native-select.tsx +0 -61
- package/src/interfaces/web/src/components/ui/navigation-menu.tsx +0 -168
- package/src/interfaces/web/src/components/ui/pagination.tsx +0 -130
- package/src/interfaces/web/src/components/ui/progress.tsx +0 -83
- package/src/interfaces/web/src/components/ui/radio-group.tsx +0 -36
- package/src/interfaces/web/src/components/ui/resizable.tsx +0 -50
- package/src/interfaces/web/src/components/ui/scroll-area.tsx +0 -53
- package/src/interfaces/web/src/components/ui/sidebar.tsx +0 -726
- package/src/interfaces/web/src/components/ui/slider.tsx +0 -52
- package/src/interfaces/web/src/components/ui/sonner.tsx +0 -49
- package/src/interfaces/web/src/components/ui/table.tsx +0 -116
- package/src/interfaces/web/src/components/ui/toggle-group.tsx +0 -87
- package/src/interfaces/web/src/components/ui/toggle.tsx +0 -45
- package/src/interfaces/web/src/hooks/use-mobile.ts +0 -19
- package/src/interfaces/web/src/screens/base/GlobalTasksTab.tsx +0 -161
|
@@ -6,13 +6,19 @@
|
|
|
6
6
|
// GET /tts/providers → { configured_provider, mode, order,
|
|
7
7
|
// engines: [{id, available, configured, enabled}] }
|
|
8
8
|
//
|
|
9
|
+
// GET /tts/voices?provider=<id>
|
|
10
|
+
// → { voices: [name] } — the speakers a self-hosted
|
|
11
|
+
// endpoint actually has, so the settings form can
|
|
12
|
+
// offer them instead of asking for a typed guess.
|
|
13
|
+
//
|
|
9
14
|
// Audio files land under ~/.apx/tmp/tts/<uuid>.<ext>. The caller (CLI,
|
|
10
15
|
// Telegram plugin, overlay) is responsible for picking them up.
|
|
11
16
|
import { synthesize, listProviders } from "#core/voice/tts.js";
|
|
12
17
|
import { readConfig } from "#core/config/index.js";
|
|
18
|
+
import { asyncRoute } from "./shared.js";
|
|
13
19
|
|
|
14
20
|
export function register(api) {
|
|
15
|
-
api.post("/tts/say", async (req, res) => {
|
|
21
|
+
api.post("/tts/say", asyncRoute(async (req, res) => {
|
|
16
22
|
try {
|
|
17
23
|
const { text, voice, language, provider, format, style } = req.body || {};
|
|
18
24
|
if (typeof text !== "string" || !text.trim()) {
|
|
@@ -31,14 +37,101 @@ export function register(api) {
|
|
|
31
37
|
} catch (e) {
|
|
32
38
|
res.status(500).json({ error: e.message });
|
|
33
39
|
}
|
|
34
|
-
});
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
// GET /tts/warmup — tell the engine that would speak next to get ready.
|
|
43
|
+
// The desktop calls this the moment the mic opens, so the model is resident
|
|
44
|
+
// by the time there is a reply to say.
|
|
45
|
+
api.get("/tts/warmup", asyncRoute(async (_req, res) => {
|
|
46
|
+
const { warmupTts } = await import("#core/voice/tts.js");
|
|
47
|
+
res.json(await warmupTts());
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
// GET /tts/reachable — does the local voice server actually answer right now?
|
|
51
|
+
//
|
|
52
|
+
// Deliberately not folded into /tts/providers. The `available` flag there is
|
|
53
|
+
// a CONFIG probe by design: a custom endpoint reports itself available on the
|
|
54
|
+
// strength of having a base_url, which is the right answer for a settings
|
|
55
|
+
// list that must show an engine you are still setting up. It is the wrong
|
|
56
|
+
// answer for "is it running" — stop the server and that flag never moves.
|
|
57
|
+
//
|
|
58
|
+
// Only ever probes a self-hosted endpoint, and only /models, the
|
|
59
|
+
// OpenAI-compatible catalogue every such server already serves. A short
|
|
60
|
+
// timeout because the point is to distinguish answering from not, and a
|
|
61
|
+
// server that needs three seconds to list its models is not answering.
|
|
62
|
+
api.get("/tts/reachable", asyncRoute(async (_req, res) => {
|
|
63
|
+
try {
|
|
64
|
+
const { resolveTtsCandidates } = await import("#core/voice/engines/index.js");
|
|
65
|
+
const { isSelfHosted } = await import("../tts-keepwarm.js");
|
|
66
|
+
const cfg = readConfig();
|
|
67
|
+
const candidates = await resolveTtsCandidates({ globalConfig: cfg });
|
|
68
|
+
const local = candidates.find((c) => isSelfHosted(c.engineConfig?.base_url));
|
|
69
|
+
if (!local) return res.json({ configured: false });
|
|
70
|
+
|
|
71
|
+
const url = String(local.engineConfig.base_url).replace(/\/+$/, "") + "/models";
|
|
72
|
+
const t0 = Date.now();
|
|
73
|
+
let reachable = false;
|
|
74
|
+
try {
|
|
75
|
+
const r = await fetch(url, { signal: AbortSignal.timeout(2500) });
|
|
76
|
+
reachable = r.ok;
|
|
77
|
+
} catch { reachable = false; }
|
|
78
|
+
res.json({
|
|
79
|
+
configured: true,
|
|
80
|
+
provider: local.provider,
|
|
81
|
+
base_url: local.engineConfig.base_url,
|
|
82
|
+
reachable,
|
|
83
|
+
ms: Date.now() - t0,
|
|
84
|
+
});
|
|
85
|
+
} catch (e) {
|
|
86
|
+
res.status(500).json({ error: e.message });
|
|
87
|
+
}
|
|
88
|
+
}));
|
|
89
|
+
|
|
90
|
+
// GET /tts/voices — the speakers a custom endpoint offers right now.
|
|
91
|
+
//
|
|
92
|
+
// The base_url comes from the stored config and never from the query: this
|
|
93
|
+
// route makes the daemon fetch a URL on request, and the set of URLs it will
|
|
94
|
+
// fetch has to stay the set the user already configured. A provider that is
|
|
95
|
+
// still being typed into the form therefore has no list — the field falls
|
|
96
|
+
// back to free text, which is what it was before.
|
|
97
|
+
api.get("/tts/voices", asyncRoute(async (req, res) => {
|
|
98
|
+
try {
|
|
99
|
+
const { providerConfig } = await import("#core/voice/engines/index.js");
|
|
100
|
+
const cfg = providerConfig(readConfig(), String(req.query.provider || ""));
|
|
101
|
+
const base = cfg?.base_url;
|
|
102
|
+
if (!base) return res.json({ voices: [], configured: false });
|
|
103
|
+
|
|
104
|
+
const url = String(base).replace(/\/+$/, "") + "/voices";
|
|
105
|
+
const r = await fetch(url, { signal: AbortSignal.timeout(4000) });
|
|
106
|
+
if (!r.ok) return res.json({ voices: [], reachable: false });
|
|
107
|
+
const json = await r.json();
|
|
108
|
+
const voices = Array.isArray(json?.voices)
|
|
109
|
+
? json.voices.filter((v) => typeof v === "string")
|
|
110
|
+
: [];
|
|
111
|
+
// `details` and `language` are optional: an endpoint that says which
|
|
112
|
+
// language each voice was recorded in gets labelled with it, and one that
|
|
113
|
+
// doesn't (QVox) still answers with a plain list.
|
|
114
|
+
res.json({
|
|
115
|
+
voices,
|
|
116
|
+
...(json?.details && typeof json.details === "object" ? { details: json.details } : {}),
|
|
117
|
+
...(typeof json?.language === "string" ? { language: json.language } : {}),
|
|
118
|
+
...(typeof json?.lang === "string" ? { lang: json.lang } : {}),
|
|
119
|
+
configured: true,
|
|
120
|
+
reachable: true,
|
|
121
|
+
});
|
|
122
|
+
} catch {
|
|
123
|
+
// A server that is down or speaks a different dialect is not an error
|
|
124
|
+
// here: it means "no list", and the form degrades to free text.
|
|
125
|
+
res.json({ voices: [], reachable: false });
|
|
126
|
+
}
|
|
127
|
+
}));
|
|
35
128
|
|
|
36
|
-
api.get("/tts/providers", async (_req, res) => {
|
|
129
|
+
api.get("/tts/providers", asyncRoute(async (_req, res) => {
|
|
37
130
|
try {
|
|
38
131
|
const info = await listProviders(readConfig());
|
|
39
132
|
res.json(info);
|
|
40
133
|
} catch (e) {
|
|
41
134
|
res.status(500).json({ error: e.message });
|
|
42
135
|
}
|
|
43
|
-
});
|
|
136
|
+
}));
|
|
44
137
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// The two halves of "the user stopped this turn", shared by the chat routes so
|
|
2
|
+
// the project-agent stream and the super-agent stream agree on what an
|
|
3
|
+
// interruption looks like.
|
|
4
|
+
//
|
|
5
|
+
// It is a normal outcome, not a failure. A turn that was interrupted has
|
|
6
|
+
// usually done real work the user watched happen, and the whole point of
|
|
7
|
+
// interrupting (rather than waiting) is to redirect that work with a new
|
|
8
|
+
// message — so the partial has to survive into the thread, and the client has
|
|
9
|
+
// to be able to tell "you stopped this" apart from "this broke".
|
|
10
|
+
|
|
11
|
+
// `wasAborted` moved to core when the group cascade needed the same test and
|
|
12
|
+
// core/ cannot import from host/ (rule 8). Re-exported here because this module
|
|
13
|
+
// is where every route already asks the question.
|
|
14
|
+
export { wasAborted } from "#core/agent/abort.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The terminal stream event for an interrupted turn. Deliberately NOT `error`:
|
|
18
|
+
* a client that renders errors as a red banner would accuse the daemon of
|
|
19
|
+
* breaking every time the user pressed stop.
|
|
20
|
+
*/
|
|
21
|
+
export function abortedTurnEvent({ text = "", trace = [] } = {}) {
|
|
22
|
+
return { type: "aborted", result: { text, trace } };
|
|
23
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Stopping a turn that is already running.
|
|
2
|
+
//
|
|
3
|
+
// Every other surface could already do this. Telegram has kept one
|
|
4
|
+
// AbortController per chat since the beginning — a new message aborts the
|
|
5
|
+
// running turn ("no, stop, do this instead"), and the desktop capsule has its
|
|
6
|
+
// own cancel. The web panel had neither: its Stop button aborted the browser's
|
|
7
|
+
// fetch and nothing else, so the run kept going, kept calling tools, and
|
|
8
|
+
// persisted its answer to a thread nobody was watching. Sending a message
|
|
9
|
+
// mid-turn could only queue behind it.
|
|
10
|
+
//
|
|
11
|
+
// The reason the socket closing cannot itself stop the run is deliberate: a
|
|
12
|
+
// refresh, or a second tab, has to be able to catch up on a turn in progress
|
|
13
|
+
// (see active-turns.js). So cancelling has to be said out loud, which is this
|
|
14
|
+
// route.
|
|
15
|
+
//
|
|
16
|
+
// Addressed the way the client already addresses the thread, because that is
|
|
17
|
+
// the identity it has on hand:
|
|
18
|
+
// project agent → { conversation_id }
|
|
19
|
+
// super-agent → { channel } (its thread IS the channel; see
|
|
20
|
+
// superAgentTurnKey)
|
|
21
|
+
// group room → { channel: "group", thread_id }
|
|
22
|
+
//
|
|
23
|
+
// The third form is the general one: a channel that holds MANY threads needs to
|
|
24
|
+
// say which. A group is the case that has it — one project runs any number of
|
|
25
|
+
// rooms at once, so `channel` alone would stop whichever of them the map
|
|
26
|
+
// happened to hold. A cascade is also the turn most worth stopping, since a
|
|
27
|
+
// single owner line can fan out into ten full tool loops.
|
|
28
|
+
import { asyncRoute } from "./shared.js";
|
|
29
|
+
import { abortActiveTurn, convTurnKey, superAgentTurnKey, threadTurnKey } from "../active-turns.js";
|
|
30
|
+
|
|
31
|
+
export function register(api, { project }) {
|
|
32
|
+
api.post("/projects/:pid/turns/abort", asyncRoute(async (req, res) => {
|
|
33
|
+
const p = project(req, res);
|
|
34
|
+
if (!p) return;
|
|
35
|
+
const { conversation_id: conversationId, channel, thread_id: threadId } = req.body || {};
|
|
36
|
+
if (!conversationId && !channel) {
|
|
37
|
+
return res.status(400).json({ error: "conversation_id or channel required" });
|
|
38
|
+
}
|
|
39
|
+
const key = conversationId
|
|
40
|
+
? convTurnKey(p.id, conversationId)
|
|
41
|
+
: threadId
|
|
42
|
+
? threadTurnKey(p.id, channel, threadId)
|
|
43
|
+
: superAgentTurnKey(p.id, channel);
|
|
44
|
+
// `false` is not an error: the turn may have finished a moment before the
|
|
45
|
+
// click landed, and a client that interrupts by sending should carry on and
|
|
46
|
+
// send either way.
|
|
47
|
+
res.json({ ok: true, aborted: abortActiveTurn(key) });
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
@@ -32,6 +32,7 @@ import { buildVoiceChannelContext } from "#core/agent/channels/voice-context.js"
|
|
|
32
32
|
import { extractSuggestions } from "#core/agent/suggestions.js";
|
|
33
33
|
import { appendGlobalMessage } from "#core/stores/messages.js";
|
|
34
34
|
import { appendErrorTrace, previewText } from "#core/logging.js";
|
|
35
|
+
import { asyncRoute } from "./shared.js";
|
|
35
36
|
|
|
36
37
|
export function register(api, { projects, plugins, registries }) {
|
|
37
38
|
// GET /voice/tts?path=<abs>
|
|
@@ -39,7 +40,7 @@ export function register(api, { projects, plugins, registries }) {
|
|
|
39
40
|
// Streams a TTS audio file back to the caller. Sandboxed to the
|
|
40
41
|
// ~/.apx/tmp/tts directory so a client can't request arbitrary
|
|
41
42
|
// filesystem paths through a manifest-leaked reply_audio_path.
|
|
42
|
-
api.get("/voice/tts", async (req, res) => {
|
|
43
|
+
api.get("/voice/tts", asyncRoute(async (req, res) => {
|
|
43
44
|
const rawPath = String(req.query.path || "");
|
|
44
45
|
if (!rawPath) return res.status(400).json({ error: "path required" });
|
|
45
46
|
try {
|
|
@@ -64,9 +65,9 @@ export function register(api, { projects, plugins, registries }) {
|
|
|
64
65
|
} catch (e) {
|
|
65
66
|
res.status(500).json({ error: e?.message || "tts read failed" });
|
|
66
67
|
}
|
|
67
|
-
});
|
|
68
|
+
}));
|
|
68
69
|
|
|
69
|
-
api.post("/voice/turn", async (req, res) => {
|
|
70
|
+
api.post("/voice/turn", asyncRoute(async (req, res) => {
|
|
70
71
|
const body = req.body || {};
|
|
71
72
|
const cfg = readConfig();
|
|
72
73
|
let userText = (body.text || "").trim();
|
|
@@ -261,7 +262,7 @@ export function register(api, { projects, plugins, registries }) {
|
|
|
261
262
|
}
|
|
262
263
|
}
|
|
263
264
|
}
|
|
264
|
-
});
|
|
265
|
+
}));
|
|
265
266
|
}
|
|
266
267
|
|
|
267
268
|
// Note for plugin authors:
|
|
@@ -32,7 +32,14 @@ const WEB_DIST = path.resolve(__dirname, "..", "..", "..", "interfaces", "web",
|
|
|
32
32
|
const SPA_ROUTES = [
|
|
33
33
|
/^\/$/,
|
|
34
34
|
/^\/settings(\/.*)?$/,
|
|
35
|
+
// The panel's own modules. They used to live under /m/, which now belongs to
|
|
36
|
+
// the phone surface; both spellings resolve (the old one client-side).
|
|
37
|
+
/^\/(inbox|code|desktop|voice|deck)(\/.*)?$/,
|
|
35
38
|
/^\/m\/(voice|desktop|deck|code|inbox)(\/.*)?$/,
|
|
39
|
+
// The phone: /m/chat, /m/tasks, /m/commitments — and /mobile, its old
|
|
40
|
+
// address, which redirects rather than 404s.
|
|
41
|
+
/^\/m(\/.*)?$/,
|
|
42
|
+
/^\/mobile(\/.*)?$/,
|
|
36
43
|
/^\/p\/[^/]+(\/.*)?$/,
|
|
37
44
|
];
|
|
38
45
|
|
|
@@ -40,6 +47,80 @@ export function isKnownSpaRoute(p) {
|
|
|
40
47
|
return SPA_ROUTES.some((re) => re.test(p));
|
|
41
48
|
}
|
|
42
49
|
|
|
50
|
+
// Content types for the compressed twins. Needed because the file being sent
|
|
51
|
+
// ends in `.br`/`.gz`, and express would otherwise call a brotli-compressed
|
|
52
|
+
// stylesheet application/octet-stream — which a browser refuses to apply.
|
|
53
|
+
const TYPE_BY_EXT = {
|
|
54
|
+
".js": "application/javascript; charset=UTF-8",
|
|
55
|
+
".css": "text/css; charset=UTF-8",
|
|
56
|
+
".html": "text/html; charset=UTF-8",
|
|
57
|
+
".svg": "image/svg+xml",
|
|
58
|
+
".json": "application/json; charset=UTF-8",
|
|
59
|
+
".webmanifest": "application/manifest+json",
|
|
60
|
+
".map": "application/json; charset=UTF-8",
|
|
61
|
+
".txt": "text/plain; charset=UTF-8",
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** The encodings this client will take, best first. */
|
|
65
|
+
function acceptedEncodings(header) {
|
|
66
|
+
// Order by our preference, not the client's q-values: brotli is smaller and
|
|
67
|
+
// every browser that offers it prefers it too.
|
|
68
|
+
const raw = String(header || "").toLowerCase();
|
|
69
|
+
const out = [];
|
|
70
|
+
if (/\bbr\b/.test(raw)) out.push({ enc: "br", ext: ".br" });
|
|
71
|
+
if (/\bgzip\b/.test(raw)) out.push({ enc: "gzip", ext: ".gz" });
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Serve `foo.js.br` when the client asked for brotli and the file exists.
|
|
77
|
+
*
|
|
78
|
+
* Deliberately a lookup and a sendFile rather than compressing per request:
|
|
79
|
+
* these files do not change between builds, so the work belongs in the build
|
|
80
|
+
* (see scripts/build-web.js), and brotli at maximum quality — worth another
|
|
81
|
+
* ~20% over gzip — is far too slow to do on the fly.
|
|
82
|
+
*
|
|
83
|
+
* A dist with no twins (an older build, or a dev checkout) falls straight
|
|
84
|
+
* through to express.static, uncompressed and working.
|
|
85
|
+
*/
|
|
86
|
+
export function servePrecompressed(root) {
|
|
87
|
+
return function precompressed(req, res, next) {
|
|
88
|
+
if (req.method !== "GET" && req.method !== "HEAD") return next();
|
|
89
|
+
const ext = path.extname(req.path).toLowerCase();
|
|
90
|
+
const type = TYPE_BY_EXT[ext];
|
|
91
|
+
if (!type) return next();
|
|
92
|
+
|
|
93
|
+
// The client may be behind a proxy that varies on encoding; say so
|
|
94
|
+
// regardless of whether we end up compressing, so a cache keyed on the URL
|
|
95
|
+
// alone cannot hand a brotli body to a client that cannot read it.
|
|
96
|
+
res.setHeader("Vary", "Accept-Encoding");
|
|
97
|
+
|
|
98
|
+
const rel = decodeURIComponent(req.path).replace(/^\/+/, "");
|
|
99
|
+
// Same containment rule as the media route: resolve, then require the
|
|
100
|
+
// result to still be inside the directory we are serving.
|
|
101
|
+
const target = path.resolve(root, rel);
|
|
102
|
+
if (target !== root && !target.startsWith(root + path.sep)) return next();
|
|
103
|
+
|
|
104
|
+
for (const { enc, ext: suffix } of acceptedEncodings(req.headers["accept-encoding"])) {
|
|
105
|
+
const twin = `${target}${suffix}`;
|
|
106
|
+
if (!fs.existsSync(twin)) continue;
|
|
107
|
+
res.setHeader("Content-Encoding", enc);
|
|
108
|
+
res.setHeader("Content-Type", type);
|
|
109
|
+
// index.html is the SPA shell and must never be cached; its twin is the
|
|
110
|
+
// same file and inherits the same rule.
|
|
111
|
+
res.setHeader("Cache-Control", rel.endsWith("index.html") || rel.endsWith("sw.js") ? "no-cache" : "public, max-age=3600");
|
|
112
|
+
// acceptRanges off: a byte range of the COMPRESSED file is not a byte
|
|
113
|
+
// range of the resource, and a client that asked for one would decode
|
|
114
|
+
// garbage. Nothing range-requests a stylesheet, but the header would be
|
|
115
|
+
// an invitation to.
|
|
116
|
+
return res.sendFile(twin, { acceptRanges: false }, (err) => {
|
|
117
|
+
if (err) next(err);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
return next();
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
43
124
|
// /api/admin/web-token: localhost-only endpoint that returns the daemon token
|
|
44
125
|
// so the same-origin admin panel can authenticate every subsequent call.
|
|
45
126
|
// Refuses if the request didn't come from loopback. Also refuses if the
|
|
@@ -108,6 +189,16 @@ export function register(app, { express }) {
|
|
|
108
189
|
return;
|
|
109
190
|
}
|
|
110
191
|
|
|
192
|
+
// Precompressed twins first: the build writes `.br` and `.gz` next to every
|
|
193
|
+
// compressible asset, and this hands over whichever one the client asked for.
|
|
194
|
+
//
|
|
195
|
+
// The bundle is ~1.7 MB of JavaScript and every byte of it used to go out
|
|
196
|
+
// raw. On loopback that is invisible; over Tailscale, where the connection
|
|
197
|
+
// may be relayed through a DERP node on another continent, it is the whole
|
|
198
|
+
// difference between the panel opening at once and the phone sitting on a
|
|
199
|
+
// white screen. Brotli takes it to ~400 KB.
|
|
200
|
+
app.use(servePrecompressed(WEB_DIST));
|
|
201
|
+
|
|
111
202
|
// Serve static assets. NB: we mount AFTER the /api router is mounted in
|
|
112
203
|
// api.js so data routes always win over this catch-all.
|
|
113
204
|
app.use(
|
|
@@ -121,6 +212,13 @@ export function register(app, { express }) {
|
|
|
121
212
|
if (filePath.endsWith("index.html")) {
|
|
122
213
|
res.setHeader("Cache-Control", "no-cache");
|
|
123
214
|
}
|
|
215
|
+
// The service worker decides what the installed app is allowed to
|
|
216
|
+
// reuse; a cached copy of it would keep deciding with yesterday's
|
|
217
|
+
// rules. Browsers already revalidate this file, but an hour of
|
|
218
|
+
// max-age here is one hour of pinning a policy we may have fixed.
|
|
219
|
+
if (filePath.endsWith("sw.js")) {
|
|
220
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
221
|
+
}
|
|
124
222
|
},
|
|
125
223
|
})
|
|
126
224
|
);
|
package/src/host/daemon/api.js
CHANGED
|
@@ -13,11 +13,13 @@
|
|
|
13
13
|
import express from "express";
|
|
14
14
|
|
|
15
15
|
import { API_PREFIX } from "./api/prefix.js";
|
|
16
|
+
import { effectiveHost, effectivePort } from "#core/config/index.js";
|
|
16
17
|
import { logError } from "#core/logging.js";
|
|
17
18
|
|
|
18
19
|
import {
|
|
19
20
|
traceIdMiddleware,
|
|
20
21
|
buildAuthMiddleware,
|
|
22
|
+
buildRequestLogger,
|
|
21
23
|
makeProjectResolver,
|
|
22
24
|
makeTopProjectResolver,
|
|
23
25
|
errorMiddleware,
|
|
@@ -31,18 +33,22 @@ import { register as registerSessions } from "./api/sessions.js";
|
|
|
31
33
|
import { register as registerMcps } from "./api/mcps.js";
|
|
32
34
|
import { register as registerIntegrations } from "./api/integrations.js";
|
|
33
35
|
import { register as registerVars } from "./api/vars.js";
|
|
36
|
+
import { register as registerMedia } from "./api/media.js";
|
|
34
37
|
import { register as registerMessages } from "./api/messages.js";
|
|
35
38
|
import { register as registerTelegram } from "./api/telegram.js";
|
|
36
39
|
import { register as registerPlugins } from "./api/plugins.js";
|
|
37
40
|
import { register as registerEngines } from "./api/engines.js";
|
|
38
41
|
import { register as registerSkills } from "./api/skills.js";
|
|
39
42
|
import { register as registerExec } from "./api/exec.js";
|
|
43
|
+
import { register as registerTurns } from "./api/turns.js";
|
|
40
44
|
import { register as registerSuperAgent } from "./api/super-agent.js";
|
|
41
45
|
import { register as registerCode } from "./api/code.js";
|
|
42
46
|
import { register as registerConversations } from "./api/conversations.js";
|
|
47
|
+
import { register as registerGroups } from "./api/groups.js";
|
|
43
48
|
import { register as registerConnections } from "./api/connections.js";
|
|
44
49
|
import { register as registerRuntimes } from "./api/runtimes.js";
|
|
45
50
|
import { register as registerRoutines } from "./api/routines.js";
|
|
51
|
+
import { register as registerDeliveries } from "./api/deliveries.js";
|
|
46
52
|
import { register as registerArtifacts } from "./api/artifacts.js";
|
|
47
53
|
import { register as registerArtifactPreview } from "./api/artifact-preview.js";
|
|
48
54
|
import { register as registerTasks } from "./api/tasks.js";
|
|
@@ -55,6 +61,7 @@ import { register as registerTopLevel } from "./api/top-level.js";
|
|
|
55
61
|
import { register as registerSessionsSearch } from "./api/sessions-search.js";
|
|
56
62
|
import { register as registerTranscribe } from "./api/transcribe.js";
|
|
57
63
|
import { register as registerTts } from "./api/tts.js";
|
|
64
|
+
import { register as registerImages } from "./api/images.js";
|
|
58
65
|
import { register as registerEmbeddings } from "./api/embeddings.js";
|
|
59
66
|
import { register as registerVoice } from "./api/voice.js";
|
|
60
67
|
import { register as registerDesktop } from "./api/desktop.js";
|
|
@@ -69,6 +76,8 @@ import { register as registerSelfMemory } from "./api/self-memory.js";
|
|
|
69
76
|
import { register as registerNudges } from "./api/nudges.js";
|
|
70
77
|
import { register as registerWeb, registerWebToken } from "./api/web.js";
|
|
71
78
|
import { register as registerConfirm } from "./api/confirm.js";
|
|
79
|
+
import { register as registerNet, corsBetweenOwnAddresses } from "./api/net.js";
|
|
80
|
+
import { register as registerMobility } from "./api/mobility.js";
|
|
72
81
|
|
|
73
82
|
export function buildApi({
|
|
74
83
|
projects,
|
|
@@ -81,6 +90,9 @@ export function buildApi({
|
|
|
81
90
|
config,
|
|
82
91
|
token,
|
|
83
92
|
tokenStore,
|
|
93
|
+
mobilityDispatch,
|
|
94
|
+
mobilityPositionDispatch,
|
|
95
|
+
log,
|
|
84
96
|
}) {
|
|
85
97
|
const telegram = plugins?.get("telegram");
|
|
86
98
|
const app = express();
|
|
@@ -91,6 +103,24 @@ export function buildApi({
|
|
|
91
103
|
// ---- Global middleware -------------------------------------------
|
|
92
104
|
app.use(express.json({ limit: "2mb" }));
|
|
93
105
|
app.use(traceIdMiddleware);
|
|
106
|
+
// One daemon answers on several addresses (loopback, the LAN, the tailnet).
|
|
107
|
+
// A panel installed from one of them may fail over to another; that is a
|
|
108
|
+
// cross-origin request to the same process, and only OUR other addresses are
|
|
109
|
+
// allowed to make it. Must sit above the auth wall so a preflight — which
|
|
110
|
+
// carries no Authorization header by definition — is answered rather than
|
|
111
|
+
// rejected as unauthenticated.
|
|
112
|
+
app.use(corsBetweenOwnAddresses({ port: effectivePort(config), host: effectiveHost(config) }));
|
|
113
|
+
// Above the auth wall so 401s from a client with a stale token are logged
|
|
114
|
+
// too — see buildRequestLogger. No-op when the daemon didn't pass a logger
|
|
115
|
+
// (tests build the app directly).
|
|
116
|
+
if (typeof log === "function") {
|
|
117
|
+
app.use(
|
|
118
|
+
buildRequestLogger({
|
|
119
|
+
log,
|
|
120
|
+
match: (p) => p.startsWith(API_PREFIX) && p.includes("/super-agent/"),
|
|
121
|
+
})
|
|
122
|
+
);
|
|
123
|
+
}
|
|
94
124
|
// Prefer the multi-token store when provided (production path); fall
|
|
95
125
|
// back to the single `token` argument for legacy callers and tests
|
|
96
126
|
// that haven't migrated yet.
|
|
@@ -117,6 +147,8 @@ export function buildApi({
|
|
|
117
147
|
resolveTopProject,
|
|
118
148
|
token,
|
|
119
149
|
tokenStore,
|
|
150
|
+
mobilityDispatch,
|
|
151
|
+
mobilityPositionDispatch,
|
|
120
152
|
};
|
|
121
153
|
|
|
122
154
|
// ---- Tool routers — must mount BEFORE wildcard registry below ----
|
|
@@ -132,17 +164,22 @@ export function buildApi({
|
|
|
132
164
|
registerMcps(api, ctx);
|
|
133
165
|
registerIntegrations(api, ctx);
|
|
134
166
|
registerVars(api, ctx);
|
|
167
|
+
registerMedia(api);
|
|
135
168
|
registerMessages(api, ctx);
|
|
136
169
|
registerEngines(api, ctx);
|
|
137
170
|
registerSkills(api, ctx);
|
|
138
171
|
registerExec(api, ctx);
|
|
172
|
+
registerTurns(api, ctx);
|
|
139
173
|
registerSuperAgent(api, ctx);
|
|
140
174
|
registerConfirm(api, ctx);
|
|
175
|
+
registerNet(api, ctx);
|
|
141
176
|
registerCode(api, ctx);
|
|
142
177
|
registerConversations(api, ctx);
|
|
178
|
+
registerGroups(api, ctx);
|
|
143
179
|
registerConnections(api, ctx);
|
|
144
180
|
registerRuntimes(api, ctx);
|
|
145
181
|
registerRoutines(api, ctx);
|
|
182
|
+
registerDeliveries(api, ctx);
|
|
146
183
|
registerArtifacts(api, ctx);
|
|
147
184
|
registerArtifactPreview(api, ctx);
|
|
148
185
|
registerTasks(api, ctx);
|
|
@@ -161,10 +198,12 @@ export function buildApi({
|
|
|
161
198
|
registerPlugins(api, ctx);
|
|
162
199
|
registerTranscribe(api, ctx);
|
|
163
200
|
registerTts(api, ctx);
|
|
201
|
+
registerImages(api, ctx);
|
|
164
202
|
registerEmbeddings(api, ctx);
|
|
165
203
|
registerVoice(api, ctx);
|
|
166
204
|
registerDesktop(api, ctx);
|
|
167
205
|
registerDeck(api, ctx);
|
|
206
|
+
registerMobility(api, ctx);
|
|
168
207
|
registerPairing(api, ctx);
|
|
169
208
|
|
|
170
209
|
// ---- Admin -------------------------------------------------------
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// The delivery grace sweep — the "notify unless he reads it first" timer.
|
|
2
|
+
//
|
|
3
|
+
// An ORDINARY (non-priority) delivery is not pinged at the moment it is created.
|
|
4
|
+
// It sits `pending` for a short grace window so Manu can open the agent's chat
|
|
5
|
+
// and reply — which marks it `answered` and cancels the notify (answerDeliveries,
|
|
6
|
+
// wired into the agent-chat endpoint). If the window passes and it is still
|
|
7
|
+
// pending, this sweep has Roby tell him.
|
|
8
|
+
//
|
|
9
|
+
// Priority/anchor deliveries do NOT come through here — the runner notifies those
|
|
10
|
+
// immediately. This is only the deferred half.
|
|
11
|
+
//
|
|
12
|
+
// Cheap by construction: it wakes on a plain interval, and a tick with nothing
|
|
13
|
+
// past its grace does no work and touches no model. A held send (quiet-hours,
|
|
14
|
+
// budget) is LEFT pending so a later tick retries once the budget allows —
|
|
15
|
+
// canNudge holds it before composing, so a retry costs nothing until it lands.
|
|
16
|
+
import { listDeliveries, markDelivery, DELIVERY_STATUS } from "#core/stores/deliveries.js";
|
|
17
|
+
import { notifyOwnerViaRoby } from "#core/routines/delivery.js";
|
|
18
|
+
|
|
19
|
+
const GRACE_MS = 60_000; // time to read/answer before Roby pings (ordinary only)
|
|
20
|
+
const SWEEP_MS = 30_000; // how often the daemon checks the queue
|
|
21
|
+
|
|
22
|
+
export function startDeliverySweep({ projects, plugins, registries, config } = {}) {
|
|
23
|
+
async function tick() {
|
|
24
|
+
const now = Date.now();
|
|
25
|
+
for (const entry of projects?.list?.() || []) {
|
|
26
|
+
let p;
|
|
27
|
+
try { p = projects.get(entry.id); } catch { continue; }
|
|
28
|
+
if (!p?.storagePath) continue;
|
|
29
|
+
|
|
30
|
+
const due = listDeliveries(p.storagePath, { status: DELIVERY_STATUS.PENDING }).filter(
|
|
31
|
+
(d) => d.priority !== true && d.created_at && now - Date.parse(d.created_at) >= GRACE_MS,
|
|
32
|
+
);
|
|
33
|
+
if (!due.length) continue;
|
|
34
|
+
|
|
35
|
+
const globalConfig = p.config || config || {};
|
|
36
|
+
const ctx = { project: p, plugins, registries, globalConfig };
|
|
37
|
+
for (const d of due) {
|
|
38
|
+
const gate = { severity: "normal", scheduled: false, unsolicited: true, project_id: entry.id };
|
|
39
|
+
try {
|
|
40
|
+
const r = await notifyOwnerViaRoby(ctx, {
|
|
41
|
+
routine: { name: d.routine || "delivery", id: d.routine_id || "" },
|
|
42
|
+
agent: { slug: d.agent, name: d.agent_name },
|
|
43
|
+
text: d.notify,
|
|
44
|
+
notify: d.notify,
|
|
45
|
+
gate,
|
|
46
|
+
});
|
|
47
|
+
if (r?.sent) markDelivery(p.storagePath, d.id, DELIVERY_STATUS.NOTIFIED, { channel: "telegram" });
|
|
48
|
+
// held / skipped → leave it pending; a later tick retries when the
|
|
49
|
+
// budget allows or the telegram plugin comes back.
|
|
50
|
+
} catch { /* best-effort — the delivery stays pending and is retried */ }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const timer = setInterval(() => { tick().catch(() => {}); }, SWEEP_MS);
|
|
56
|
+
timer.unref?.();
|
|
57
|
+
return function stop() { clearInterval(timer); };
|
|
58
|
+
}
|
|
@@ -11,15 +11,12 @@ export function setDesktopMessageHandler(fn) {
|
|
|
11
11
|
_messageHandler = fn;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
// --- WS upgrade auth
|
|
14
|
+
// --- WS upgrade auth ---
|
|
15
15
|
//
|
|
16
|
-
// The desktop
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
// this, any client that can reach the daemon (loopback by default, but the LAN
|
|
21
|
-
// when host is set to 0.0.0.0) could open the channel and drive the
|
|
22
|
-
// super-agent. See QA BUG-WS-AUTH.
|
|
16
|
+
// The desktop channel authenticates the same way every other WS channel and
|
|
17
|
+
// every HTTP /api route does. The check itself lives in ws-auth.js — it is not
|
|
18
|
+
// a desktop rule, it is the daemon's rule — and only the PATH is the desktop's
|
|
19
|
+
// own. See that file for why it may not be duplicated per channel.
|
|
23
20
|
|
|
24
21
|
/** The desktop channel's upgrade path. Lives under /api like every other route. */
|
|
25
22
|
export const DESKTOP_WS_PATH = apiPath("/desktop/ws");
|
|
@@ -31,21 +28,6 @@ export function isDesktopUpgradePath(url) {
|
|
|
31
28
|
return pathname === DESKTOP_WS_PATH;
|
|
32
29
|
}
|
|
33
30
|
|
|
34
|
-
/** Extract the bearer token from the upgrade request (header first, ?token= fallback). */
|
|
35
|
-
export function extractWsToken(req) {
|
|
36
|
-
const auth = (req && req.headers && req.headers["authorization"]) || "";
|
|
37
|
-
if (auth.startsWith("Bearer ")) return auth.slice(7);
|
|
38
|
-
try {
|
|
39
|
-
return new URL((req && req.url) || "", "http://localhost").searchParams.get("token") || "";
|
|
40
|
-
} catch { return ""; }
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** True iff the upgrade request carries a token the store recognizes. */
|
|
44
|
-
export function isDesktopUpgradeAuthorized(req, tokenStore) {
|
|
45
|
-
if (!tokenStore || typeof tokenStore.has !== "function") return false;
|
|
46
|
-
return tokenStore.has(extractWsToken(req));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
31
|
export function registerDesktopClient(ws) {
|
|
50
32
|
_clients.add(ws);
|
|
51
33
|
ws.on("close", () => _clients.delete(ws));
|