@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
|
@@ -54,20 +54,71 @@ def _load_model_if_needed(model_name, device, compute_type):
|
|
|
54
54
|
return m
|
|
55
55
|
|
|
56
56
|
|
|
57
|
+
def _silent_clip_path():
|
|
58
|
+
"""A one-second 16 kHz mono WAV of near-silence, written to a temp file.
|
|
59
|
+
|
|
60
|
+
Deliberately not pure zeroes: a digitally silent clip can be short-circuited
|
|
61
|
+
before the model runs, which is the opposite of what a warmup wants.
|
|
62
|
+
"""
|
|
63
|
+
import struct
|
|
64
|
+
import tempfile
|
|
65
|
+
|
|
66
|
+
rate, secs = 16000, 1
|
|
67
|
+
frames = rate * secs
|
|
68
|
+
# A whisper of dither — inaudible, but real samples the model must decode.
|
|
69
|
+
pcm = b"".join(struct.pack("<h", (i % 7) - 3) for i in range(frames))
|
|
70
|
+
data_size = len(pcm)
|
|
71
|
+
header = (
|
|
72
|
+
b"RIFF" + struct.pack("<I", 36 + data_size) + b"WAVEfmt "
|
|
73
|
+
+ struct.pack("<IHHIIHH", 16, 1, 1, rate, rate * 2, 2, 16)
|
|
74
|
+
+ b"data" + struct.pack("<I", data_size)
|
|
75
|
+
)
|
|
76
|
+
tmp = tempfile.NamedTemporaryFile(suffix=".wav", delete=False)
|
|
77
|
+
tmp.write(header + pcm)
|
|
78
|
+
tmp.close()
|
|
79
|
+
return tmp.name
|
|
80
|
+
|
|
81
|
+
|
|
57
82
|
def _warmup_model():
|
|
58
|
-
"""
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
83
|
+
"""Make the model ready to answer FAST, not merely resident.
|
|
84
|
+
|
|
85
|
+
Loading the weights is only half the cost. On MLX the first real
|
|
86
|
+
transcription also compiles the Metal graph, and that half is the expensive
|
|
87
|
+
one: measured on this machine, a freshly loaded model still spent ~10s on
|
|
88
|
+
its first utterance and 0.7s on every one after it. A warmup that stops at
|
|
89
|
+
load_model() therefore moves nothing — the user goes on paying the compile.
|
|
90
|
+
|
|
91
|
+
So we transcribe a throwaway clip. It costs the daemon a second at boot and
|
|
92
|
+
takes the stall out of the first thing anyone says.
|
|
93
|
+
"""
|
|
94
|
+
global _mlx_loaded, _model
|
|
95
|
+
clip = None
|
|
96
|
+
try:
|
|
97
|
+
if _Handler.backend == "mlx":
|
|
98
|
+
import mlx_whisper # noqa: F401 (raises ImportError if the stack is missing)
|
|
99
|
+
clip = _silent_clip_path()
|
|
100
|
+
mlx_whisper.transcribe(clip, path_or_hf_repo=_Handler.model_name)
|
|
65
101
|
_mlx_loaded = True
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
102
|
+
return True
|
|
103
|
+
_load_model_if_needed(_Handler.model_name, _Handler.device, _Handler.compute_type)
|
|
104
|
+
clip = _silent_clip_path()
|
|
105
|
+
# Consume the generator — faster-whisper decodes lazily.
|
|
106
|
+
segments, _info = _model.transcribe(clip, beam_size=1)
|
|
107
|
+
for _ in segments:
|
|
108
|
+
pass
|
|
109
|
+
return True
|
|
110
|
+
except ImportError:
|
|
111
|
+
raise
|
|
112
|
+
except Exception as e:
|
|
113
|
+
# A warmup that fails is a slow first request, not a broken server.
|
|
114
|
+
print(f"[whisper-server] warmup failed: {e}", file=sys.stderr, flush=True)
|
|
115
|
+
return _mlx_loaded if _Handler.backend == "mlx" else (_model is not None)
|
|
116
|
+
finally:
|
|
117
|
+
if clip:
|
|
118
|
+
try:
|
|
119
|
+
os.unlink(clip)
|
|
120
|
+
except Exception:
|
|
121
|
+
pass
|
|
71
122
|
|
|
72
123
|
|
|
73
124
|
def _transcribe_file(audio_path, language, beam_size):
|
|
@@ -141,7 +192,13 @@ class _Handler(BaseHTTPRequestHandler):
|
|
|
141
192
|
|
|
142
193
|
def do_GET(self):
|
|
143
194
|
if self.path == "/health":
|
|
144
|
-
_touch()
|
|
195
|
+
# Deliberately does NOT _touch(). A health check is someone asking
|
|
196
|
+
# whether we are alive, not someone using us — and because the
|
|
197
|
+
# desktop window polls /health, counting it as use kept the idle
|
|
198
|
+
# watchdog permanently reset. The server then lived for days
|
|
199
|
+
# holding a port while its weights were long since paged out: it
|
|
200
|
+
# neither died nor stayed warm. Real use (/transcribe, /warmup)
|
|
201
|
+
# is what resets the timer now.
|
|
145
202
|
loaded = _mlx_loaded if _Handler.backend == "mlx" else (_model is not None)
|
|
146
203
|
self._send_json(200, {
|
|
147
204
|
"ok": True,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Who may open a WebSocket on this daemon.
|
|
2
|
+
//
|
|
3
|
+
// Every WS channel here is gated the same way and for the same reason: the
|
|
4
|
+
// daemon binds 0.0.0.0 when the panel is reachable from the LAN or a tailnet,
|
|
5
|
+
// so "can reach the port" is not "may open a channel". The upgrade request must
|
|
6
|
+
// carry a token the store already knows — the master token or a paired client's
|
|
7
|
+
// — exactly like the HTTP routes do. See QA BUG-WS-AUTH.
|
|
8
|
+
//
|
|
9
|
+
// One home for the check (rule 8): it started inside desktop-ws.js, which was
|
|
10
|
+
// fine while the desktop was the only channel. It now guards the terminal and
|
|
11
|
+
// the live event feed too, and a per-channel copy is how one of them ends up
|
|
12
|
+
// with a weaker rule than the others.
|
|
13
|
+
|
|
14
|
+
/** Extract the bearer token from an upgrade request (header first, ?token= fallback).
|
|
15
|
+
* Browsers cannot set headers on a WebSocket handshake, hence the query fallback. */
|
|
16
|
+
export function extractWsToken(req) {
|
|
17
|
+
const auth = (req && req.headers && req.headers["authorization"]) || "";
|
|
18
|
+
if (auth.startsWith("Bearer ")) return auth.slice(7);
|
|
19
|
+
try {
|
|
20
|
+
return new URL((req && req.url) || "", "http://localhost").searchParams.get("token") || "";
|
|
21
|
+
} catch { return ""; }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** True iff the upgrade request carries a token the store recognizes. */
|
|
25
|
+
export function isWsUpgradeAuthorized(req, tokenStore) {
|
|
26
|
+
if (!tokenStore || typeof tokenStore.has !== "function") return false;
|
|
27
|
+
return tokenStore.has(extractWsToken(req));
|
|
28
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
plugins {
|
|
2
|
+
id "com.android.application"
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
android {
|
|
6
|
+
namespace "dev.agentprojectcontext.apx"
|
|
7
|
+
compileSdk 35
|
|
8
|
+
|
|
9
|
+
defaultConfig {
|
|
10
|
+
applicationId "dev.agentprojectcontext.apx"
|
|
11
|
+
minSdk 26
|
|
12
|
+
targetSdk 35
|
|
13
|
+
versionCode 1
|
|
14
|
+
versionName "0.1.0"
|
|
15
|
+
|
|
16
|
+
testInstrumentationRunner "android.test.InstrumentationTestRunner"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
buildTypes {
|
|
20
|
+
release {
|
|
21
|
+
minifyEnabled false
|
|
22
|
+
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
compileOptions {
|
|
27
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
28
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
dependencies {
|
|
33
|
+
implementation "androidx.core:core:1.16.0"
|
|
34
|
+
implementation "com.squareup.okhttp3:okhttp:4.12.0"
|
|
35
|
+
// The Android Auto chip. A MessagingStyle notification only ever gets two
|
|
36
|
+
// controls on a head unit (reply, mark-read), so four answers need the
|
|
37
|
+
// template library — see ApxCarAppService.
|
|
38
|
+
implementation "androidx.car.app:app:1.4.0"
|
|
39
|
+
implementation "androidx.car.app:app-projected:1.4.0"
|
|
40
|
+
testImplementation "junit:junit:4.13.2"
|
|
41
|
+
testImplementation "org.json:json:20240303"
|
|
42
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
4
|
+
<!-- Not for dialling out: the socket's reconnect ladder asks whether there
|
|
5
|
+
is any network at all before it retries, and wakes on the callback
|
|
6
|
+
instead of on a timer. A phone away from the daemon used to retry
|
|
7
|
+
every 15 s all day. -->
|
|
8
|
+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
9
|
+
<!-- So the notification socket survives a reboot. Without it APX is silent
|
|
10
|
+
from the moment the phone restarts until someone opens the app, and
|
|
11
|
+
nothing about that looks broken from the outside. -->
|
|
12
|
+
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
|
13
|
+
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
|
14
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
15
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
|
|
16
|
+
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
17
|
+
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
|
|
18
|
+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
|
19
|
+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
20
|
+
<!-- A foreground service typed `location` is what lets APX keep reading
|
|
21
|
+
the position while the phone is in a pocket or a dock, WITHOUT asking
|
|
22
|
+
for ACCESS_BACKGROUND_LOCATION: the ongoing notification is the
|
|
23
|
+
permission model. Tracking runs only while a trip is active. -->
|
|
24
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
|
|
25
|
+
<!-- Asked for from the native menu and nowhere else: on this phone Android
|
|
26
|
+
holds back the trip's start and end events until the owner exempts APX
|
|
27
|
+
by hand, and that is a system decision, not one an app may make for
|
|
28
|
+
them. -->
|
|
29
|
+
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
|
30
|
+
|
|
31
|
+
<application
|
|
32
|
+
android:allowBackup="false"
|
|
33
|
+
android:icon="@mipmap/ic_launcher"
|
|
34
|
+
android:label="@string/app_name"
|
|
35
|
+
android:networkSecurityConfig="@xml/network_security_config"
|
|
36
|
+
android:roundIcon="@mipmap/ic_launcher_round"
|
|
37
|
+
android:supportsRtl="true"
|
|
38
|
+
android:theme="@style/AppTheme"
|
|
39
|
+
android:usesCleartextTraffic="true">
|
|
40
|
+
|
|
41
|
+
<meta-data
|
|
42
|
+
android:name="com.google.android.gms.car.application"
|
|
43
|
+
android:resource="@xml/automotive_app_desc" />
|
|
44
|
+
|
|
45
|
+
<!-- The lowest car API this app needs. 1 is the floor and everything
|
|
46
|
+
used here (ListTemplate, Row, CarToast) is in it — asking for more
|
|
47
|
+
would hide the chip on older head units for no gained feature. -->
|
|
48
|
+
<meta-data
|
|
49
|
+
android:name="androidx.car.app.minCarApiLevel"
|
|
50
|
+
android:value="1" />
|
|
51
|
+
|
|
52
|
+
<!-- The chip itself. exported=true because the HOST starts it: Android
|
|
53
|
+
Auto binds this service to draw the screen. HostValidator inside is
|
|
54
|
+
what decides which hosts are allowed to. -->
|
|
55
|
+
<service
|
|
56
|
+
android:name=".ApxCarAppService"
|
|
57
|
+
android:exported="true">
|
|
58
|
+
<intent-filter>
|
|
59
|
+
<action android:name="androidx.car.app.CarAppService" />
|
|
60
|
+
<!-- POI: APX points at places you have an errand for. It is not
|
|
61
|
+
a navigation app (Maps does the driving) and not a media
|
|
62
|
+
one, and claiming either category would put it in the wrong
|
|
63
|
+
part of the launcher. -->
|
|
64
|
+
<category android:name="androidx.car.app.category.POI" />
|
|
65
|
+
</intent-filter>
|
|
66
|
+
</service>
|
|
67
|
+
|
|
68
|
+
<activity
|
|
69
|
+
android:name=".MainActivity"
|
|
70
|
+
android:exported="true"
|
|
71
|
+
android:launchMode="singleTask">
|
|
72
|
+
<intent-filter>
|
|
73
|
+
<action android:name="android.intent.action.MAIN" />
|
|
74
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
|
75
|
+
</intent-filter>
|
|
76
|
+
<intent-filter>
|
|
77
|
+
<action android:name="android.intent.action.VIEW" />
|
|
78
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
79
|
+
<category android:name="android.intent.category.BROWSABLE" />
|
|
80
|
+
<data android:scheme="apx" android:host="pair" />
|
|
81
|
+
</intent-filter>
|
|
82
|
+
<intent-filter android:label="Compartir viaje con APX">
|
|
83
|
+
<action android:name="android.intent.action.SEND" />
|
|
84
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
85
|
+
<data android:mimeType="text/plain" />
|
|
86
|
+
</intent-filter>
|
|
87
|
+
</activity>
|
|
88
|
+
|
|
89
|
+
<service
|
|
90
|
+
android:name=".MascotOverlayService"
|
|
91
|
+
android:exported="false"
|
|
92
|
+
android:foregroundServiceType="specialUse">
|
|
93
|
+
<property
|
|
94
|
+
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
|
|
95
|
+
android:value="User-enabled floating APX mascot and live message indicator" />
|
|
96
|
+
</service>
|
|
97
|
+
|
|
98
|
+
<service
|
|
99
|
+
android:name=".TripLocationService"
|
|
100
|
+
android:exported="false"
|
|
101
|
+
android:foregroundServiceType="location" />
|
|
102
|
+
|
|
103
|
+
<service
|
|
104
|
+
android:name=".MapsNavigationListenerService"
|
|
105
|
+
android:exported="false"
|
|
106
|
+
android:label="Detección de viajes APX"
|
|
107
|
+
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
|
108
|
+
<intent-filter>
|
|
109
|
+
<action android:name="android.service.notification.NotificationListenerService" />
|
|
110
|
+
</intent-filter>
|
|
111
|
+
</service>
|
|
112
|
+
|
|
113
|
+
<receiver
|
|
114
|
+
android:name=".CarMessageActionReceiver"
|
|
115
|
+
android:exported="false" />
|
|
116
|
+
|
|
117
|
+
<!-- The four proximity answers. Not exported: only our own
|
|
118
|
+
PendingIntents fire it, and an exported receiver would let any app
|
|
119
|
+
answer an alert on the owner's behalf. -->
|
|
120
|
+
<receiver
|
|
121
|
+
android:name=".ProximityActionReceiver"
|
|
122
|
+
android:exported="false" />
|
|
123
|
+
|
|
124
|
+
<!-- exported=true because both of these are SYSTEM broadcasts: the
|
|
125
|
+
sender is Android, not APX, and a non-exported receiver is never
|
|
126
|
+
handed them. MY_PACKAGE_REPLACED is the app's own update, which
|
|
127
|
+
force-stops it and leaves the service down. -->
|
|
128
|
+
<receiver
|
|
129
|
+
android:name=".StartupReceiver"
|
|
130
|
+
android:exported="true">
|
|
131
|
+
<intent-filter>
|
|
132
|
+
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
|
133
|
+
</intent-filter>
|
|
134
|
+
<intent-filter>
|
|
135
|
+
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
|
136
|
+
</intent-filter>
|
|
137
|
+
</receiver>
|
|
138
|
+
</application>
|
|
139
|
+
</manifest>
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
package dev.agentprojectcontext.apx;
|
|
2
|
+
|
|
3
|
+
import android.content.Intent;
|
|
4
|
+
import android.net.Uri;
|
|
5
|
+
import android.util.Log;
|
|
6
|
+
|
|
7
|
+
import androidx.annotation.NonNull;
|
|
8
|
+
import androidx.car.app.CarContext;
|
|
9
|
+
import androidx.car.app.CarToast;
|
|
10
|
+
import androidx.car.app.Screen;
|
|
11
|
+
import androidx.car.app.model.Action;
|
|
12
|
+
import androidx.car.app.model.ItemList;
|
|
13
|
+
import androidx.car.app.model.ListTemplate;
|
|
14
|
+
import androidx.car.app.model.Row;
|
|
15
|
+
import androidx.car.app.model.Template;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* One proximity alert on the head unit, with its four answers.
|
|
19
|
+
*
|
|
20
|
+
* A LIST, NOT A MESSAGE TEMPLATE. `MessageTemplate` takes two actions; there
|
|
21
|
+
* are four here, and dropping two of them would mean the car offering a
|
|
22
|
+
* different question than the phone. Rows are the only shape on this platform
|
|
23
|
+
* that holds four choices, and they are also the biggest touch targets it
|
|
24
|
+
* draws — which is what you want from a control used at speed.
|
|
25
|
+
*
|
|
26
|
+
* The text is read aloud by Assistant, which is why the daemon strips emoji
|
|
27
|
+
* before it ever reaches here (core/mobility/geofence.js) and why nothing in
|
|
28
|
+
* this file decorates it.
|
|
29
|
+
*/
|
|
30
|
+
final class AlertScreen extends Screen {
|
|
31
|
+
private static final String TAG = "APXTravel";
|
|
32
|
+
|
|
33
|
+
private final String alertId;
|
|
34
|
+
|
|
35
|
+
AlertScreen(@NonNull CarContext carContext, @NonNull String alertId) {
|
|
36
|
+
super(carContext);
|
|
37
|
+
this.alertId = alertId;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
@NonNull
|
|
42
|
+
public Template onGetTemplate() {
|
|
43
|
+
MessageFrameParser.MobilityAlert alert = CarAlertStore.get(alertId);
|
|
44
|
+
if (alert == null) {
|
|
45
|
+
// Answered elsewhere — on the phone, or on Telegram — while this
|
|
46
|
+
// screen was open. Say so and go back rather than offering answers
|
|
47
|
+
// to a question that is already settled.
|
|
48
|
+
return new ListTemplate.Builder()
|
|
49
|
+
.setSingleList(new ItemList.Builder()
|
|
50
|
+
.addItem(new Row.Builder()
|
|
51
|
+
.setTitle(getCarContext().getString(R.string.car_alert_gone))
|
|
52
|
+
.build())
|
|
53
|
+
.build())
|
|
54
|
+
.setTitle(getCarContext().getString(R.string.car_trip_title))
|
|
55
|
+
.setHeaderAction(Action.BACK)
|
|
56
|
+
.build();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ItemList.Builder items = new ItemList.Builder();
|
|
60
|
+
// The alert itself, as the first row: on a head unit the title bar is
|
|
61
|
+
// one line, and the address does not fit in it.
|
|
62
|
+
items.addItem(new Row.Builder()
|
|
63
|
+
.setTitle(alert.title())
|
|
64
|
+
.addText(alert.body())
|
|
65
|
+
.build());
|
|
66
|
+
|
|
67
|
+
// The daemon owns the four and their wording. Android renders what it
|
|
68
|
+
// was sent — a fifth answer would need no new APK.
|
|
69
|
+
for (MessageFrameParser.Action action : alert.actions()) {
|
|
70
|
+
items.addItem(new Row.Builder()
|
|
71
|
+
.setTitle(action.label())
|
|
72
|
+
.setBrowsable(false)
|
|
73
|
+
.setOnClickListener(() -> answer(alert, action.id()))
|
|
74
|
+
.build());
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return new ListTemplate.Builder()
|
|
78
|
+
.setSingleList(items.build())
|
|
79
|
+
.setTitle(alert.title())
|
|
80
|
+
.setHeaderAction(Action.BACK)
|
|
81
|
+
.build();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Answer, then navigate — the same order the phone's receiver uses, for the
|
|
86
|
+
* same reason: handing the screen to Maps is where an answer gets lost.
|
|
87
|
+
*/
|
|
88
|
+
private void answer(MessageFrameParser.MobilityAlert alert, String actionId) {
|
|
89
|
+
ApxPreferences preferences = new ApxPreferences(getCarContext());
|
|
90
|
+
DaemonClient.answerAlert(
|
|
91
|
+
preferences.daemonUrl(),
|
|
92
|
+
preferences.token(),
|
|
93
|
+
alert.id(),
|
|
94
|
+
actionId,
|
|
95
|
+
new DaemonClient.AnswerCallback() {
|
|
96
|
+
@Override public void onAnswered() {
|
|
97
|
+
Log.i(TAG, "car answer " + actionId + " recorded for " + alert.id());
|
|
98
|
+
}
|
|
99
|
+
@Override public void onAnswerFailed(String message) {
|
|
100
|
+
Log.w(TAG, "car answer " + actionId + " failed: " + message);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// Locally too: the head unit must not keep offering an answered alert
|
|
106
|
+
// while the daemon's reply is still in flight over a mobile link.
|
|
107
|
+
CarAlertStore.remove(alert.id());
|
|
108
|
+
ProximityNotification.cancel(getCarContext(), ProximityNotification.notificationId(alert.id()));
|
|
109
|
+
|
|
110
|
+
String url = switch (actionId) {
|
|
111
|
+
case "navigate" -> alert.navigateUrl();
|
|
112
|
+
case "add_stop" -> alert.addStopUrl();
|
|
113
|
+
default -> null;
|
|
114
|
+
};
|
|
115
|
+
if (url != null && !url.isBlank()) {
|
|
116
|
+
try {
|
|
117
|
+
// The car host owns which navigation app runs; handing it a
|
|
118
|
+
// plain geo/Maps intent is how an app asks for a route without
|
|
119
|
+
// taking over the screen itself.
|
|
120
|
+
getCarContext().startCarApp(new Intent(CarContext.ACTION_NAVIGATE, Uri.parse(url)));
|
|
121
|
+
} catch (Exception error) {
|
|
122
|
+
Log.w(TAG, "car navigate refused: " + error.getMessage());
|
|
123
|
+
CarToast.makeText(getCarContext(),
|
|
124
|
+
getCarContext().getString(R.string.car_navigate_failed),
|
|
125
|
+
CarToast.LENGTH_SHORT).show();
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
CarToast.makeText(getCarContext(), okText(actionId), CarToast.LENGTH_SHORT).show();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
getScreenManager().pop();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private String okText(String actionId) {
|
|
135
|
+
return "skip".equals(actionId)
|
|
136
|
+
? getCarContext().getString(R.string.car_ack_dismissed)
|
|
137
|
+
: getCarContext().getString(R.string.car_ack_later);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
package dev.agentprojectcontext.apx;
|
|
2
|
+
|
|
3
|
+
import java.text.Normalizer;
|
|
4
|
+
import java.util.Locale;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Recognises "the phone is projecting to Android Auto right now" from the
|
|
8
|
+
* notification Android Auto itself posts while a session is live.
|
|
9
|
+
*
|
|
10
|
+
* Why the notification and not the Car App Library: CarConnection would mean
|
|
11
|
+
* pulling androidx.car.app in for one boolean, and its content provider is
|
|
12
|
+
* only queryable by apps the Auto host already knows about. APX is not a car
|
|
13
|
+
* app — it is a phone app that wants to know the owner is driving — and it
|
|
14
|
+
* ALREADY holds notification-listener access for the Google Maps trip
|
|
15
|
+
* detector next door. One permission, two signals.
|
|
16
|
+
*
|
|
17
|
+
* The distinction that matters and is easy to get wrong: Android Auto posts
|
|
18
|
+
* notifications when it is NOT running too ("tap to set up", "Android Auto is
|
|
19
|
+
* available", update prompts). Those are invitations, not sessions. Treating
|
|
20
|
+
* one as a connection would put APX in a trip while the phone sits on a desk,
|
|
21
|
+
* so a match needs an ongoing notification whose text reads like a running
|
|
22
|
+
* session rather than an offer to start one.
|
|
23
|
+
*/
|
|
24
|
+
final class AndroidAutoDetector {
|
|
25
|
+
static final String AUTO_PACKAGE = "com.google.android.projection.gearhead";
|
|
26
|
+
|
|
27
|
+
// A live session says it is running / connected / driving.
|
|
28
|
+
private static final String[] RUNNING_TERMS = {
|
|
29
|
+
"en ejecucion", "ejecutando", "esta corriendo", "conectado", "conectada",
|
|
30
|
+
"modo conduccion", "modo de conduccion", "en el auto", "en el coche",
|
|
31
|
+
"is running", "running", "connected", "driving mode", "in car", "car mode",
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// An invitation says: do something to make a session happen.
|
|
35
|
+
private static final String[] OFFER_TERMS = {
|
|
36
|
+
"toca para", "tocar para", "presiona", "configur", "instal", "actualiz",
|
|
37
|
+
"disponible", "prueba", "conecta tu", "conecta el",
|
|
38
|
+
"tap to", "set up", "setup", "install", "update", "available", "try ",
|
|
39
|
+
"connect your",
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Developer mode posts its own persistent notification while the head unit
|
|
43
|
+
// SERVER is listening — "Programador de Android Auto · Servidor de unidad
|
|
44
|
+
// principal en ejecución". A server waiting for a head unit is not a car,
|
|
45
|
+
// and on a phone with developer mode left on it would otherwise hold APX
|
|
46
|
+
// in a permanent trip. Found on a real device while testing against the
|
|
47
|
+
// Desktop Head Unit, which is exactly when that notification exists.
|
|
48
|
+
private static final String[] DEVELOPER_TERMS = {
|
|
49
|
+
"programador", "developer", "servidor de unidad principal", "head unit server",
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
private AndroidAutoDetector() {}
|
|
53
|
+
|
|
54
|
+
/** Every notification this app must inspect for a projection session. */
|
|
55
|
+
static boolean isAutoPackage(String packageName) {
|
|
56
|
+
return AUTO_PACKAGE.equals(packageName);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* True when this notification is Android Auto reporting a LIVE projection
|
|
61
|
+
* session. An offer to set Auto up is never a session, no matter how it is
|
|
62
|
+
* worded, so the offer check wins over the running check.
|
|
63
|
+
*
|
|
64
|
+
* `persistent` must be computed from BOTH FLAG_ONGOING_EVENT and
|
|
65
|
+
* FLAG_FOREGROUND_SERVICE. A real session on a Galaxy A55 posts
|
|
66
|
+
* "Android Auto · Conectado al vehículo" with flags NO_CLEAR |
|
|
67
|
+
* FOREGROUND_SERVICE and no ONGOING_EVENT at all: gating on the ongoing
|
|
68
|
+
* flag alone silently detected nothing, on the one signal this feature
|
|
69
|
+
* exists for. A foreground-service notification is the stronger claim of
|
|
70
|
+
* the two anyway — a service is actually running behind it.
|
|
71
|
+
*/
|
|
72
|
+
static boolean isProjectionActive(
|
|
73
|
+
String packageName,
|
|
74
|
+
boolean persistent,
|
|
75
|
+
CharSequence title,
|
|
76
|
+
CharSequence text
|
|
77
|
+
) {
|
|
78
|
+
if (!isAutoPackage(packageName)) return false;
|
|
79
|
+
// A session notification cannot be swiped away while the car screen is
|
|
80
|
+
// up. An announcement can.
|
|
81
|
+
if (!persistent) return false;
|
|
82
|
+
|
|
83
|
+
String content = normalize(String.valueOf(title) + " " + String.valueOf(text));
|
|
84
|
+
if (containsAny(content, DEVELOPER_TERMS)) return false;
|
|
85
|
+
if (containsAny(content, OFFER_TERMS)) return false;
|
|
86
|
+
if (containsAny(content, RUNNING_TERMS)) return true;
|
|
87
|
+
// Android Auto localises this notification into languages this list
|
|
88
|
+
// does not cover, and an ongoing notification from the projection app
|
|
89
|
+
// that is not an offer is a session in every one of them. Falling back
|
|
90
|
+
// to "yes" here is deliberate: the alternative is a driver whose phone
|
|
91
|
+
// never notices the car it is plugged into.
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private static boolean containsAny(String value, String... needles) {
|
|
96
|
+
for (String needle : needles) {
|
|
97
|
+
if (value.contains(needle)) return true;
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private static String normalize(String value) {
|
|
103
|
+
String lower = value.toLowerCase(Locale.ROOT);
|
|
104
|
+
return Normalizer.normalize(lower, Normalizer.Form.NFD).replaceAll("\\p{M}+", "");
|
|
105
|
+
}
|
|
106
|
+
}
|
package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxCarAppService.java
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
package dev.agentprojectcontext.apx;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import androidx.car.app.CarAppService;
|
|
5
|
+
import androidx.car.app.Session;
|
|
6
|
+
import androidx.car.app.Screen;
|
|
7
|
+
import androidx.car.app.validation.HostValidator;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* APX on the head unit — the chip in Android Auto's launcher, beside Maps and
|
|
11
|
+
* whatever is playing music.
|
|
12
|
+
*
|
|
13
|
+
* WHY A CAR APP AND NOT A NOTIFICATION. Android Auto renders a MessagingStyle
|
|
14
|
+
* notification with exactly two controls: reply and mark-as-read. That is the
|
|
15
|
+
* shape of a chat, and a proximity alert is not one — it is four answers, and
|
|
16
|
+
* the two of them that matter most ("Navegar ahora", "Sumar a la ruta") are
|
|
17
|
+
* navigation actions a messaging card has no way to offer. The template
|
|
18
|
+
* library is the only surface on this platform that draws four.
|
|
19
|
+
*
|
|
20
|
+
* It shows the trip: where the car is going, and the errands APX is watching
|
|
21
|
+
* for along the way. When something comes into range the alert goes to the top
|
|
22
|
+
* of that same list, so the driver's glance lands in one place instead of
|
|
23
|
+
* hunting a banner that has already gone.
|
|
24
|
+
*
|
|
25
|
+
* NOTHING HERE PAINTS ANYTHING ITSELF. Templates are described and the host
|
|
26
|
+
* draws them, which is what keeps the app legal to use while driving — the
|
|
27
|
+
* platform enforces the reading limits, not us.
|
|
28
|
+
*/
|
|
29
|
+
public final class ApxCarAppService extends CarAppService {
|
|
30
|
+
|
|
31
|
+
@Override
|
|
32
|
+
@NonNull
|
|
33
|
+
public HostValidator createHostValidator() {
|
|
34
|
+
// Debug builds talk to the Desktop Head Unit, which is not a signed
|
|
35
|
+
// Google host — pinning the production allowlist here would make the
|
|
36
|
+
// whole feature untestable without a car. Release builds keep the
|
|
37
|
+
// real check: an unvalidated host can drive the screen.
|
|
38
|
+
if ((getApplicationInfo().flags & android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
|
|
39
|
+
return HostValidator.ALLOW_ALL_HOSTS_VALIDATOR;
|
|
40
|
+
}
|
|
41
|
+
return new HostValidator.Builder(getApplicationContext())
|
|
42
|
+
.addAllowedHosts(androidx.car.app.R.array.hosts_allowlist_sample)
|
|
43
|
+
.build();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Override
|
|
47
|
+
@NonNull
|
|
48
|
+
public Session onCreateSession() {
|
|
49
|
+
return new Session() {
|
|
50
|
+
@Override
|
|
51
|
+
@NonNull
|
|
52
|
+
public Screen onCreateScreen(@NonNull android.content.Intent intent) {
|
|
53
|
+
return new TripScreen(getCarContext());
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|