@agentprojectcontext/apx 1.81.0 → 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 +21 -11
- 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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// Channels, as THIS DEVICE wants them.
|
|
2
|
+
//
|
|
3
|
+
// One agent is reachable from several places at once, and the inbox now shows
|
|
4
|
+
// every one of them. That is right for the list and wrong for the bell: the
|
|
5
|
+
// phone has Telegram installed ON it, so a Telegram reply announced by APX is
|
|
6
|
+
// the same event announced twice, while the same reply on the laptop is the
|
|
7
|
+
// only way to hear about it at all. There is no single correct answer, so the
|
|
8
|
+
// question is asked per device.
|
|
9
|
+
//
|
|
10
|
+
// Two independent axes, deliberately not one setting:
|
|
11
|
+
// VIEW — whose conversations appear in the lists (inbox, phone).
|
|
12
|
+
// NOTIFY — who is allowed to raise a notification.
|
|
13
|
+
// Hiding Telegram threads from the phone list and still wanting a bell for them
|
|
14
|
+
// is a coherent position; so is the reverse.
|
|
15
|
+
//
|
|
16
|
+
// Stored in localStorage because that IS the scope of the question — per
|
|
17
|
+
// origin, per device, and untouched by another browser signing in. Only
|
|
18
|
+
// EXPLICIT choices are stored: an absent channel falls through to the default
|
|
19
|
+
// for the surface, so a channel invented after this code shipped behaves
|
|
20
|
+
// sensibly instead of being silently muted.
|
|
21
|
+
import { isInstalled } from "./net";
|
|
22
|
+
import { t } from "../i18n";
|
|
23
|
+
|
|
24
|
+
export type ChannelAxis = "view" | "notify";
|
|
25
|
+
|
|
26
|
+
const KEYS: Record<ChannelAxis, string> = {
|
|
27
|
+
view: "apx.channels.view",
|
|
28
|
+
notify: "apx.channels.notify",
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** Proper nouns, mostly, so they read the same in either locale. The two that
|
|
32
|
+
* are descriptions rather than names go through i18n. Anything unknown shows
|
|
33
|
+
* its raw value rather than being hidden — a channel nobody named is exactly
|
|
34
|
+
* the one worth seeing. */
|
|
35
|
+
const CHANNEL_LABELS: Record<string, string> = {
|
|
36
|
+
whatsapp: "WhatsApp",
|
|
37
|
+
telegram: "Telegram",
|
|
38
|
+
web: "Web",
|
|
39
|
+
web_sidebar: "Web · sidebar",
|
|
40
|
+
web_code: "Web · code",
|
|
41
|
+
desktop: "Desktop",
|
|
42
|
+
deck: "Deck",
|
|
43
|
+
code: "Code",
|
|
44
|
+
cli: "CLI",
|
|
45
|
+
api: "API",
|
|
46
|
+
direct: "Direct",
|
|
47
|
+
routine: "Routine",
|
|
48
|
+
log: "Log",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export function channelLabel(channel: string): string {
|
|
52
|
+
if (channel === "a2a") return t("channels.a2a");
|
|
53
|
+
if (channel === "group") return t("channels.group");
|
|
54
|
+
if (channel === "other") return t("channels.other");
|
|
55
|
+
// Not a channel a conversation happens on — a kind of news the phone can
|
|
56
|
+
// ring for (the trip bubbles). It only ever appears in the APK's notify
|
|
57
|
+
// list, which is why it is a description and goes through i18n.
|
|
58
|
+
if (channel === "mobility") return t("channels.mobility");
|
|
59
|
+
return CHANNEL_LABELS[channel] || channel;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Is this the phone shell, rather than the panel?
|
|
64
|
+
*
|
|
65
|
+
* Installed counts (the APK and an installed PWA both open on the phone
|
|
66
|
+
* surface), and so does simply being on one of its routes in a browser. It
|
|
67
|
+
* decides two things: the shape of the URL a notification tap lands on, and
|
|
68
|
+
* which channels are muted out of the box.
|
|
69
|
+
*
|
|
70
|
+
* `/mobile` is still matched: it is the phone's old address and the Android
|
|
71
|
+
* shell still opens it, so a tab that has not been redirected yet is still a
|
|
72
|
+
* phone. The panel's own modules used to live under `/m` too, so they are
|
|
73
|
+
* excluded by name — being one render early on `/m/code` must not make a
|
|
74
|
+
* 27-inch panel start behaving like a phone.
|
|
75
|
+
*/
|
|
76
|
+
const PANEL_MODULES_UNDER_M = /^\/m\/(inbox|code|desktop|voice|deck)(\/|$)/;
|
|
77
|
+
|
|
78
|
+
export function isPhoneSurface(): boolean {
|
|
79
|
+
if (isInstalled()) return true;
|
|
80
|
+
if (typeof location === "undefined") return false;
|
|
81
|
+
const path = location.pathname;
|
|
82
|
+
if (PANEL_MODULES_UNDER_M.test(path)) return false;
|
|
83
|
+
return path === "/m" || path.startsWith("/m/") || path.startsWith("/mobile");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Channels that start OFF on the phone.
|
|
88
|
+
*
|
|
89
|
+
* Telegram, and only Telegram: the app is on the same device, so its own
|
|
90
|
+
* notification has already arrived and its own thread is one home-screen icon
|
|
91
|
+
* away. Everything else is a place the phone cannot otherwise reach. One tap on
|
|
92
|
+
* the chip turns it back on, per axis, and that choice is then remembered
|
|
93
|
+
* instead of falling back here.
|
|
94
|
+
*/
|
|
95
|
+
const PHONE_MUTED = new Set(["telegram"]);
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Channels that never ring, on any device.
|
|
99
|
+
*
|
|
100
|
+
* `log` is the one: it exists so that output which must be READABLE but must
|
|
101
|
+
* not ARRIVE has somewhere to live — a routine's reasoning when it chose to
|
|
102
|
+
* stay quiet. A notification for that is the interruption the routine just
|
|
103
|
+
* declined to make, so the bell is off by default here rather than left to the
|
|
104
|
+
* generic "a new channel is probably worth hearing about" rule.
|
|
105
|
+
*
|
|
106
|
+
* View is untouched: the thread shows in the lists like any other, in its own
|
|
107
|
+
* channel group, and one tick in the filter hides it for a device that would
|
|
108
|
+
* rather not see it at all.
|
|
109
|
+
*/
|
|
110
|
+
const NEVER_NOTIFY = new Set(["log"]);
|
|
111
|
+
|
|
112
|
+
export function channelDefault(axis: ChannelAxis, channel: string): boolean {
|
|
113
|
+
if (axis === "notify" && NEVER_NOTIFY.has(channel)) return false;
|
|
114
|
+
return !(isPhoneSurface() && PHONE_MUTED.has(channel));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** The explicit choices on one axis. Absent channels are NOT in here. */
|
|
118
|
+
export function channelPrefs(axis: ChannelAxis): Record<string, boolean> {
|
|
119
|
+
try {
|
|
120
|
+
const raw = localStorage.getItem(KEYS[axis]);
|
|
121
|
+
if (!raw) return {};
|
|
122
|
+
const parsed = JSON.parse(raw) as unknown;
|
|
123
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
124
|
+
const out: Record<string, boolean> = {};
|
|
125
|
+
for (const [k, v] of Object.entries(parsed as Record<string, unknown>)) {
|
|
126
|
+
if (typeof v === "boolean") out[k] = v;
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
} catch {
|
|
130
|
+
return {}; // private mode, or something else wrote over the key
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** The same answer, against a map already in hand — what a React render has,
|
|
135
|
+
* and what keeps a memo dependent on a stable value instead of a closure
|
|
136
|
+
* rebuilt every render. */
|
|
137
|
+
export function channelEnabledIn(
|
|
138
|
+
prefs: Record<string, boolean>,
|
|
139
|
+
axis: ChannelAxis,
|
|
140
|
+
channel: string | null | undefined,
|
|
141
|
+
): boolean {
|
|
142
|
+
const key = channel || "other";
|
|
143
|
+
const explicit = prefs[key];
|
|
144
|
+
return explicit === undefined ? channelDefault(axis, key) : explicit;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** Should this channel be shown / announced on this device right now? */
|
|
148
|
+
export function channelEnabled(axis: ChannelAxis, channel: string | null | undefined): boolean {
|
|
149
|
+
return channelEnabledIn(channelPrefs(axis), axis, channel);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Remember a choice. Listeners (the chips, the notifier) hear about it through
|
|
153
|
+
* the event below rather than by polling storage. */
|
|
154
|
+
export function setChannelEnabled(axis: ChannelAxis, channel: string, on: boolean) {
|
|
155
|
+
const next = { ...channelPrefs(axis), [channel]: on };
|
|
156
|
+
try {
|
|
157
|
+
localStorage.setItem(KEYS[axis], JSON.stringify(next));
|
|
158
|
+
} catch {
|
|
159
|
+
/* private mode: it holds for this session, which is all we can offer */
|
|
160
|
+
}
|
|
161
|
+
emitChange(axis);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Turn a whole set on or off in one write — "show everything again" is one
|
|
165
|
+
* decision, not eleven, and eleven writes would be eleven re-renders. */
|
|
166
|
+
export function setChannelsEnabled(axis: ChannelAxis, channels: string[], on: boolean) {
|
|
167
|
+
const next = { ...channelPrefs(axis) };
|
|
168
|
+
for (const channel of channels) next[channel] = on;
|
|
169
|
+
try {
|
|
170
|
+
localStorage.setItem(KEYS[axis], JSON.stringify(next));
|
|
171
|
+
} catch {
|
|
172
|
+
/* private mode: it holds for this session, which is all we can offer */
|
|
173
|
+
}
|
|
174
|
+
emitChange(axis);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// A same-tab change fires nothing on its own — `storage` only reaches OTHER
|
|
178
|
+
// tabs — so the chips and the notifier would keep rendering the old answer
|
|
179
|
+
// until something else re-rendered them.
|
|
180
|
+
const CHANGE_EVENT = "apx:channel-prefs";
|
|
181
|
+
|
|
182
|
+
function emitChange(axis: ChannelAxis) {
|
|
183
|
+
try {
|
|
184
|
+
window.dispatchEvent(new CustomEvent(CHANGE_EVENT, { detail: { axis } }));
|
|
185
|
+
} catch {
|
|
186
|
+
/* no window (SSR, a test): nothing is listening anyway */
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Subscribe to preference changes, from this tab or another one. */
|
|
191
|
+
export function onChannelPrefsChange(fn: () => void): () => void {
|
|
192
|
+
const local = () => fn();
|
|
193
|
+
const remote = (e: StorageEvent) => {
|
|
194
|
+
if (!e.key || e.key === KEYS.view || e.key === KEYS.notify) fn();
|
|
195
|
+
};
|
|
196
|
+
window.addEventListener(CHANGE_EVENT, local);
|
|
197
|
+
window.addEventListener("storage", remote);
|
|
198
|
+
return () => {
|
|
199
|
+
window.removeEventListener(CHANGE_EVENT, local);
|
|
200
|
+
window.removeEventListener("storage", remote);
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** The channels present in a set of rows, most recent first (rows arrive
|
|
205
|
+
* sorted), so a filter strip offers what actually exists on this install
|
|
206
|
+
* rather than a hardcoded catalog of everything APX can speak. */
|
|
207
|
+
export function channelsOf(rows: { channel: string | null }[]): string[] {
|
|
208
|
+
const seen: string[] = [];
|
|
209
|
+
for (const row of rows) {
|
|
210
|
+
const key = row.channel || "other";
|
|
211
|
+
if (!seen.includes(key)) seen.push(key);
|
|
212
|
+
}
|
|
213
|
+
return seen;
|
|
214
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// One device-wide chat activity registry.
|
|
2
|
+
//
|
|
3
|
+
// Chat panes mount and unmount as navigation moves between Inbox, a project and
|
|
4
|
+
// the phone shell. A turn does not: it belongs to the daemon. Keeping the small
|
|
5
|
+
// UI projection here (running / unread / queued) gives every rail one contract
|
|
6
|
+
// and keeps a finished answer visible after the pane that started it is gone.
|
|
7
|
+
import { subscribeTurns } from "./live";
|
|
8
|
+
import type { ActiveTurn, TurnFrame } from "../types/daemon";
|
|
9
|
+
|
|
10
|
+
export interface ChatActivity {
|
|
11
|
+
running: boolean;
|
|
12
|
+
unread: boolean;
|
|
13
|
+
queued: number;
|
|
14
|
+
turnId?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const EMPTY: ChatActivity = Object.freeze({ running: false, unread: false, queued: 0 });
|
|
18
|
+
const state = new Map<string, ChatActivity>();
|
|
19
|
+
const visible = new Set<string>();
|
|
20
|
+
const closedTurnIds = new Set<string>();
|
|
21
|
+
const listeners = new Set<() => void>();
|
|
22
|
+
const UNREAD_KEY = "apx.chat.unread.v1";
|
|
23
|
+
let wired = false;
|
|
24
|
+
let hydrated = false;
|
|
25
|
+
|
|
26
|
+
export function conversationActivityKey(pid: string | number, conversationId: string): string {
|
|
27
|
+
return `${pid}:conv:${conversationId}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function threadActivityKey(
|
|
31
|
+
pid: string | number,
|
|
32
|
+
channel: string,
|
|
33
|
+
threadId: string,
|
|
34
|
+
): string {
|
|
35
|
+
return `${pid}:thread:${channel}:${threadId}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function liveActivityKey(pid: string | number, agentSlug: string): string {
|
|
39
|
+
return `${pid}:live:${agentSlug}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function activityKeyFromActiveTurn(active?: ActiveTurn | null): string | null {
|
|
43
|
+
if (!active || active.project_id == null) return null;
|
|
44
|
+
if (active.conversation_id) {
|
|
45
|
+
return conversationActivityKey(active.project_id, active.conversation_id);
|
|
46
|
+
}
|
|
47
|
+
if (active.channel && active.thread_id) {
|
|
48
|
+
return threadActivityKey(active.project_id, active.channel, active.thread_id);
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function frameKey(frame: TurnFrame): string | null {
|
|
54
|
+
if (frame.project_id == null) return null;
|
|
55
|
+
if (frame.conversation_id) {
|
|
56
|
+
return conversationActivityKey(frame.project_id, frame.conversation_id);
|
|
57
|
+
}
|
|
58
|
+
if (frame.channel && frame.thread_id) {
|
|
59
|
+
return threadActivityKey(frame.project_id, frame.channel, frame.thread_id);
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function hydrateUnread() {
|
|
65
|
+
if (hydrated || typeof window === "undefined") return;
|
|
66
|
+
hydrated = true;
|
|
67
|
+
try {
|
|
68
|
+
const raw = JSON.parse(localStorage.getItem(UNREAD_KEY) || "[]");
|
|
69
|
+
if (!Array.isArray(raw)) return;
|
|
70
|
+
for (const key of raw) {
|
|
71
|
+
if (typeof key === "string") state.set(key, { ...EMPTY, unread: true });
|
|
72
|
+
}
|
|
73
|
+
} catch {
|
|
74
|
+
// Private mode / corrupt preference: unread starts empty.
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function persistUnread() {
|
|
79
|
+
if (typeof window === "undefined") return;
|
|
80
|
+
try {
|
|
81
|
+
const keys = [...state.entries()].filter(([, value]) => value.unread).map(([key]) => key);
|
|
82
|
+
localStorage.setItem(UNREAD_KEY, JSON.stringify(keys));
|
|
83
|
+
} catch {
|
|
84
|
+
// Per-device hint only; storage refusal must never break chat.
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function publish() {
|
|
89
|
+
for (const listener of listeners) listener();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function patch(key: string, next: Partial<ChatActivity>) {
|
|
93
|
+
hydrateUnread();
|
|
94
|
+
const current = state.get(key) || EMPTY;
|
|
95
|
+
const value = { ...current, ...next };
|
|
96
|
+
if (!value.running && !value.unread && !value.queued) state.delete(key);
|
|
97
|
+
else state.set(key, value);
|
|
98
|
+
publish();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function onTurn(frame: TurnFrame) {
|
|
102
|
+
const key = frameKey(frame);
|
|
103
|
+
if (!key) return;
|
|
104
|
+
if (frame.phase === "start" || frame.phase === "delta") {
|
|
105
|
+
closedTurnIds.delete(frame.turn_id);
|
|
106
|
+
patch(key, { running: true, turnId: frame.turn_id });
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
closedTurnIds.add(frame.turn_id);
|
|
110
|
+
const unread = frame.phase === "final" || frame.phase === "aborted"
|
|
111
|
+
? !visible.has(key)
|
|
112
|
+
: false;
|
|
113
|
+
patch(key, { running: false, unread, turnId: undefined });
|
|
114
|
+
persistUnread();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function wire() {
|
|
118
|
+
if (wired) return;
|
|
119
|
+
wired = true;
|
|
120
|
+
hydrateUnread();
|
|
121
|
+
// Deliberately process-lifetime. Screens churn; the device-wide registry must
|
|
122
|
+
// hear the closing frame even when no chat pane happens to be mounted.
|
|
123
|
+
subscribeTurns(onTurn);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function subscribeChatActivity(listener: () => void): () => void {
|
|
127
|
+
wire();
|
|
128
|
+
listeners.add(listener);
|
|
129
|
+
return () => { listeners.delete(listener); };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function readChatActivity(key: string | null): ChatActivity {
|
|
133
|
+
hydrateUnread();
|
|
134
|
+
if (!key) return EMPTY;
|
|
135
|
+
return state.get(key) || EMPTY;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Seed a list row from the daemon snapshot. Never clears a live frame with a
|
|
139
|
+
* stale list response; closing frames own that transition. */
|
|
140
|
+
export function seedActiveTurn(key: string | null, active?: ActiveTurn | null) {
|
|
141
|
+
if (!key || !active || closedTurnIds.has(active.turn_id)) return;
|
|
142
|
+
patch(key, { running: true, turnId: active.turn_id });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** A list/detail response can have been serialized just before its turn closed
|
|
146
|
+
* frame arrived. Refuse that stale snapshot when the response reaches React. */
|
|
147
|
+
export function isChatTurnClosed(turnId?: string | null): boolean {
|
|
148
|
+
return !!turnId && closedTurnIds.has(turnId);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function setChatQueued(key: string | null, queued: number) {
|
|
152
|
+
if (!key) return;
|
|
153
|
+
patch(key, { queued: Math.max(0, queued) });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function setChatVisible(key: string | null, shown: boolean) {
|
|
157
|
+
if (!key) return;
|
|
158
|
+
wire();
|
|
159
|
+
if (shown) {
|
|
160
|
+
visible.add(key);
|
|
161
|
+
patch(key, { unread: false });
|
|
162
|
+
persistUnread();
|
|
163
|
+
} else {
|
|
164
|
+
visible.delete(key);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Test seam. */
|
|
169
|
+
export function resetChatActivity() {
|
|
170
|
+
state.clear();
|
|
171
|
+
visible.clear();
|
|
172
|
+
closedTurnIds.clear();
|
|
173
|
+
hydrated = false;
|
|
174
|
+
publish();
|
|
175
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// What this DEVICE wants a chat to do, kept out of the global config for the
|
|
2
|
+
// same reason the per-channel view/notify choices are (lib/channels.ts): the
|
|
3
|
+
// phone and the desktop are used differently by the same person, and neither
|
|
4
|
+
// should be able to change the other's behaviour by accident.
|
|
5
|
+
|
|
6
|
+
const KEY = "apx.chat.queueOnSend";
|
|
7
|
+
|
|
8
|
+
type Listener = () => void;
|
|
9
|
+
const listeners = new Set<Listener>();
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Send during a running turn: interrupt it, or wait behind it?
|
|
13
|
+
*
|
|
14
|
+
* The default is INTERRUPT, because that is what typing while an agent works
|
|
15
|
+
* almost always means — "no, stop, do this instead" — and it is what Telegram
|
|
16
|
+
* has always done (core/channels/telegram/dispatch.js aborts the running turn
|
|
17
|
+
* when a new message arrives). Queueing was the web's behaviour only because
|
|
18
|
+
* there was nothing to interrupt: no route passed a signal, so waiting was the
|
|
19
|
+
* only thing the panel could offer.
|
|
20
|
+
*
|
|
21
|
+
* Queueing is still worth having on purpose — "finish that, then do this" —
|
|
22
|
+
* which is why it stayed, as a choice rather than as the only option.
|
|
23
|
+
*/
|
|
24
|
+
export function queueOnSend(): boolean {
|
|
25
|
+
try {
|
|
26
|
+
return localStorage.getItem(KEY) === "1";
|
|
27
|
+
} catch {
|
|
28
|
+
// Private mode, blocked site data: fall back to the default rather than
|
|
29
|
+
// making the composer throw.
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function setQueueOnSend(on: boolean): void {
|
|
35
|
+
try {
|
|
36
|
+
if (on) localStorage.setItem(KEY, "1");
|
|
37
|
+
else localStorage.removeItem(KEY);
|
|
38
|
+
} catch {
|
|
39
|
+
/* nothing to persist to; the session still honours the call below */
|
|
40
|
+
}
|
|
41
|
+
for (const fn of listeners) fn();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Subscribe to changes from anywhere in this tab. Returns an unsubscribe. */
|
|
45
|
+
export function onChatPrefsChange(fn: Listener): () => void {
|
|
46
|
+
listeners.add(fn);
|
|
47
|
+
return () => listeners.delete(fn);
|
|
48
|
+
}
|
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
// where the conversation's weight sits (user vs assistant vs tool I/O).
|
|
7
7
|
import type { CodeTurn } from "./api/code";
|
|
8
8
|
|
|
9
|
-
const estTokens = (s: string): number => (s ? Math.ceil(s.length / 4) : 0);
|
|
10
|
-
|
|
11
9
|
function turnText(turn: CodeTurn, kinds: { text?: boolean; tool?: boolean }): number {
|
|
12
10
|
let chars = 0;
|
|
13
11
|
for (const p of turn.parts || []) {
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
// Typed HTTP client against the APX daemon. All requests carry the bearer
|
|
2
|
-
// token loaded once on first paint (see useTokenBootstrap). Same-origin
|
|
3
|
-
// when the daemon serves the SPA, requests land on the same port; in
|
|
2
|
+
// token loaded once on first paint (see useTokenBootstrap). Same-origin by
|
|
3
|
+
// default: when the daemon serves the SPA, requests land on the same port; in
|
|
4
4
|
// `vite dev` the proxy redirects to 7430.
|
|
5
|
+
//
|
|
6
|
+
// "By default", because an installed app launches at the address it was
|
|
7
|
+
// installed from and that address is not always reachable — the phone left the
|
|
8
|
+
// Wi-Fi, or Tailscale is off. A request that cannot reach the current address
|
|
9
|
+
// asks lib/net to find one that answers and is retried there; see that file
|
|
10
|
+
// for the whole story.
|
|
11
|
+
import { apiUrl, mayBeWrongAddress, recoverConnection, recoverIfAddressIsWrong } from "./net";
|
|
5
12
|
|
|
6
13
|
let token: string | null = null;
|
|
7
14
|
|
|
@@ -31,12 +38,30 @@ async function request<T>(
|
|
|
31
38
|
...(token ? { authorization: `Bearer ${token}` } : {}),
|
|
32
39
|
...((init.headers as Record<string, string>) || {}),
|
|
33
40
|
};
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
const send = () =>
|
|
42
|
+
fetch(apiUrl(path), {
|
|
43
|
+
...init,
|
|
44
|
+
method,
|
|
45
|
+
headers,
|
|
46
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
47
|
+
});
|
|
48
|
+
let res: Response;
|
|
49
|
+
try {
|
|
50
|
+
res = await send();
|
|
51
|
+
} catch (e) {
|
|
52
|
+
// A rejected fetch is a NETWORK failure — DNS, refused, unreachable — not
|
|
53
|
+
// an HTTP error. That is exactly the case another address might fix.
|
|
54
|
+
if ((init.signal as AbortSignal | undefined)?.aborted) throw e;
|
|
55
|
+
if ((await recoverConnection()) === null) throw e;
|
|
56
|
+
res = await send();
|
|
57
|
+
}
|
|
58
|
+
// Not every wrong address fails by rejecting. Private ranges repeat across
|
|
59
|
+
// networks, so a phone that changed Wi-Fi can reach *something* at the old
|
|
60
|
+
// address and be told 404 by a stranger. Confirm our daemon is still there
|
|
61
|
+
// before passing that on as an answer.
|
|
62
|
+
if (!res.ok && mayBeWrongAddress(res.status) && (await recoverIfAddressIsWrong())) {
|
|
63
|
+
res = await send();
|
|
64
|
+
}
|
|
40
65
|
if (!res.ok) {
|
|
41
66
|
let detail = "";
|
|
42
67
|
let parsed: unknown = null;
|
|
@@ -95,15 +120,24 @@ export async function streamNdjson<E = unknown>(
|
|
|
95
120
|
onEvent: (ev: E) => void,
|
|
96
121
|
signal?: AbortSignal
|
|
97
122
|
): Promise<void> {
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
123
|
+
const open = () =>
|
|
124
|
+
fetch(apiUrl(path), {
|
|
125
|
+
method: "POST",
|
|
126
|
+
signal,
|
|
127
|
+
headers: {
|
|
128
|
+
"content-type": "application/json",
|
|
129
|
+
...(token ? { authorization: `Bearer ${token}` } : {}),
|
|
130
|
+
},
|
|
131
|
+
body: JSON.stringify(body),
|
|
132
|
+
});
|
|
133
|
+
let res: Response;
|
|
134
|
+
try {
|
|
135
|
+
res = await open();
|
|
136
|
+
} catch (e) {
|
|
137
|
+
if (signal?.aborted) throw e;
|
|
138
|
+
if ((await recoverConnection()) === null) throw e;
|
|
139
|
+
res = await open();
|
|
140
|
+
}
|
|
107
141
|
if (!res.ok || !res.body) {
|
|
108
142
|
const text = await res.text().catch(() => "");
|
|
109
143
|
throw new HttpError(res.status, `POST ${path} → ${res.status}: ${text || "stream failed"}`);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Which thread an inbox row points at, and how to tell when it has moved.
|
|
2
|
+
//
|
|
3
|
+
// Pure on purpose: the inbox follows its selected row as the list refreshes
|
|
4
|
+
// underneath, and getting the comparison wrong is invisible until the exact day
|
|
5
|
+
// it matters. Kept out of the screen so it can be tested without a DOM.
|
|
6
|
+
|
|
7
|
+
/** The part of an inbox row that says WHICH thread it currently points at. */
|
|
8
|
+
export interface RowThread {
|
|
9
|
+
channel?: string | null;
|
|
10
|
+
conversation_id?: string | null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Has this row's thread changed since it was selected?
|
|
15
|
+
*
|
|
16
|
+
* Channel AND id, never the id alone. The super-agent's history is a ledger file
|
|
17
|
+
* per channel per DAY, so today's Telegram thread and today's web thread are
|
|
18
|
+
* both `2026-08-20` and differ only by channel. Comparing ids left the pane on
|
|
19
|
+
* the web thread while the row it belongs to had already moved to Telegram: the
|
|
20
|
+
* list showed a preview the pane could not reach.
|
|
21
|
+
*
|
|
22
|
+
* Null and undefined are the same absence — a row that never had a channel and
|
|
23
|
+
* one whose channel is null must not read as a move, or the pane would remount
|
|
24
|
+
* on every refresh.
|
|
25
|
+
*/
|
|
26
|
+
export function threadMoved(selected: RowThread, fresh: RowThread): boolean {
|
|
27
|
+
const same = (a: string | null | undefined, b: string | null | undefined) => (a ?? null) === (b ?? null);
|
|
28
|
+
return !same(selected.conversation_id, fresh.conversation_id) || !same(selected.channel, fresh.channel);
|
|
29
|
+
}
|