@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
|
@@ -1,22 +1,139 @@
|
|
|
1
1
|
import { useEffect, useRef } from "react";
|
|
2
2
|
import { MessageBubble } from "./MessageBubble";
|
|
3
|
+
import { pendingAskIndex } from "./InlineAskPanel";
|
|
3
4
|
import { Empty } from "../ui";
|
|
4
5
|
import { t } from "../../i18n";
|
|
5
|
-
import type {
|
|
6
|
+
import type { AgentFace } from "../agents/AgentAvatar";
|
|
7
|
+
import type { ChatMsg, QueuedTurn } from "../../hooks/useChat";
|
|
6
8
|
|
|
7
9
|
interface Props {
|
|
8
10
|
msgs: ChatMsg[];
|
|
11
|
+
/** Written while the current turn is still running, waiting behind it. They
|
|
12
|
+
* are drawn at the foot of the thread, where they will land. */
|
|
13
|
+
queued?: QueuedTurn[];
|
|
14
|
+
onUnqueue?: (id: string) => void;
|
|
9
15
|
onCopy: (text: string) => void;
|
|
16
|
+
/** Re-run the answer at this index (drop it and everything after). Absent →
|
|
17
|
+
* no regenerate affordance (super-agent threads, a2a, previews). */
|
|
18
|
+
onRegenerate?: (index: number) => void;
|
|
19
|
+
/** Edit the user message at this index and re-send (drop everything after). */
|
|
20
|
+
onEdit?: (index: number, text: string) => void;
|
|
21
|
+
/** Who to draw next to an assistant turn. Screens that know the cast (chat,
|
|
22
|
+
* inbox) pass it; the rest fall back to a neutral glyph. */
|
|
23
|
+
faceFor?: (msg: ChatMsg) => AgentFace;
|
|
24
|
+
/** Group style: name each speaker above their bubble, with a "traído por X"
|
|
25
|
+
* tag. Off in a 1:1. */
|
|
26
|
+
showSpeaker?: boolean;
|
|
27
|
+
/** Resolve an agent slug to a display name (for the "traído por X" tag). */
|
|
28
|
+
nameOf?: (slug: string) => string;
|
|
29
|
+
/** Full vs simple (pelado) transcript layout. Default on = show tool groups. */
|
|
30
|
+
showTools?: boolean;
|
|
31
|
+
/** Smooth-scroll to the latest turn. Nested previews turn this off. */
|
|
32
|
+
autoscroll?: boolean;
|
|
33
|
+
/** Height of whatever floats over the bottom of the thread (the composer
|
|
34
|
+
* dock). Rendered as trailing space so the last line of the conversation can
|
|
35
|
+
* always be scrolled clear of it. */
|
|
36
|
+
bottomInset?: number;
|
|
37
|
+
/** Phone shaping: no per-bubble avatar, wider bubbles. On 390px the face is
|
|
38
|
+
* 36px of width spent repeating something the header already says. */
|
|
39
|
+
compact?: boolean;
|
|
40
|
+
/** Told when the reader arrives at, or leaves, the bottom of the thread — so
|
|
41
|
+
* the host can offer a way back down while they are away from it. */
|
|
42
|
+
onAtBottomChange?: (atBottom: boolean) => void;
|
|
10
43
|
}
|
|
11
44
|
|
|
12
|
-
|
|
45
|
+
/** How close to the end still counts as being at it. A couple of lines of
|
|
46
|
+
* slack: a sub-pixel scroll position or a rounding here and there should not
|
|
47
|
+
* be what decides whether the next turn follows you. */
|
|
48
|
+
const AT_BOTTOM_SLACK = 24;
|
|
49
|
+
|
|
50
|
+
export function MessageList({
|
|
51
|
+
msgs,
|
|
52
|
+
queued = [],
|
|
53
|
+
onUnqueue,
|
|
54
|
+
onCopy,
|
|
55
|
+
onRegenerate,
|
|
56
|
+
onEdit,
|
|
57
|
+
faceFor,
|
|
58
|
+
showSpeaker,
|
|
59
|
+
nameOf,
|
|
60
|
+
showTools = true,
|
|
61
|
+
autoscroll = true,
|
|
62
|
+
bottomInset = 0,
|
|
63
|
+
compact,
|
|
64
|
+
onAtBottomChange,
|
|
65
|
+
}: Props) {
|
|
13
66
|
const bottomRef = useRef<HTMLDivElement | null>(null);
|
|
67
|
+
// Whether the reader is at the end. Read synchronously by the effect below,
|
|
68
|
+
// so it has to be a ref rather than state.
|
|
69
|
+
const pinned = useRef(true);
|
|
70
|
+
// What the host has been told, separately from what is true. Comparing
|
|
71
|
+
// against `pinned` alone swallowed the FIRST measurement whenever it happened
|
|
72
|
+
// to agree with the initial guess — and on a remount that left a host still
|
|
73
|
+
// showing "you are away from the bottom" for a list sitting at the bottom,
|
|
74
|
+
// with nothing that would ever correct it.
|
|
75
|
+
const reported = useRef<boolean | undefined>(undefined);
|
|
76
|
+
// Held in a ref so a host that hands over a fresh closure on every render
|
|
77
|
+
// does not tear down and rebuild the scroll listener underneath it.
|
|
78
|
+
const notify = useRef(onAtBottomChange);
|
|
79
|
+
notify.current = onAtBottomChange;
|
|
80
|
+
|
|
81
|
+
// Who owns "am I at the bottom", and the two things that follow from it.
|
|
82
|
+
//
|
|
83
|
+
// The dock over the bottom changes height while you use it — a draft wraps to
|
|
84
|
+
// a second line, the context panel opens, an attachment appears. Growing the
|
|
85
|
+
// trailing space alone would slide the last message underneath it, so a
|
|
86
|
+
// reader who was AT the bottom is carried back down. A reader who had
|
|
87
|
+
// scrolled up to re-read something is not.
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
const el = bottomRef.current;
|
|
90
|
+
if (!el || !autoscroll) return;
|
|
91
|
+
const scroller = scrollParentOf(el);
|
|
92
|
+
if (!scroller) return;
|
|
93
|
+
const measure = () => {
|
|
94
|
+
const at = scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight < AT_BOTTOM_SLACK;
|
|
95
|
+
pinned.current = at;
|
|
96
|
+
if (at === reported.current) return;
|
|
97
|
+
reported.current = at;
|
|
98
|
+
notify.current?.(at);
|
|
99
|
+
};
|
|
100
|
+
// Deliberately NOT measured here. At mount the list has not landed yet, so
|
|
101
|
+
// the honest answer is "miles from the bottom" — which would both flash the
|
|
102
|
+
// way-back button and, worse, tell the effect below not to land at all.
|
|
103
|
+
scroller.addEventListener("scroll", measure, { passive: true });
|
|
104
|
+
const ro = new ResizeObserver(() => {
|
|
105
|
+
if (pinned.current) el.scrollIntoView({ block: "end" });
|
|
106
|
+
});
|
|
107
|
+
ro.observe(el);
|
|
108
|
+
return () => {
|
|
109
|
+
scroller.removeEventListener("scroll", measure);
|
|
110
|
+
ro.disconnect();
|
|
111
|
+
};
|
|
112
|
+
}, [autoscroll]);
|
|
14
113
|
|
|
114
|
+
// A new turn follows the reader ONLY if the reader was already following it.
|
|
115
|
+
//
|
|
116
|
+
// This used to fire on every change to `msgs`, full stop: you scrolled up to
|
|
117
|
+
// re-read something, one more word arrived, and you were thrown back to the
|
|
118
|
+
// bottom mid-sentence. Leaving the end is a decision, and a message arriving
|
|
119
|
+
// is not a reason to overrule it — the way back down is offered instead, by
|
|
120
|
+
// whoever is hosting this list.
|
|
121
|
+
const landed = useRef(false);
|
|
15
122
|
useEffect(() => {
|
|
123
|
+
if (!autoscroll) return;
|
|
124
|
+
// Opening a thread lands at the latest. That is where a conversation is
|
|
125
|
+
// read from — not a preference to be inferred from a scroll position that
|
|
126
|
+
// does not exist yet.
|
|
127
|
+
if (!landed.current) {
|
|
128
|
+
landed.current = true;
|
|
129
|
+
bottomRef.current?.scrollIntoView({ block: "end" });
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (!pinned.current) return;
|
|
16
133
|
bottomRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
|
|
17
|
-
}, [msgs]);
|
|
134
|
+
}, [msgs, queued, autoscroll]);
|
|
18
135
|
|
|
19
|
-
if (msgs.length === 0) {
|
|
136
|
+
if (msgs.length === 0 && queued.length === 0) {
|
|
20
137
|
return (
|
|
21
138
|
<div className="grid h-full place-items-center p-6">
|
|
22
139
|
<Empty>{t("project.chat.empty")}</Empty>
|
|
@@ -24,35 +141,65 @@ export function MessageList({ msgs, onCopy }: Props) {
|
|
|
24
141
|
);
|
|
25
142
|
}
|
|
26
143
|
|
|
27
|
-
|
|
144
|
+
// Which turn's questions are still open — the one the composer is offering to
|
|
145
|
+
// answer. Everything else with an ask_questions call in it has been settled.
|
|
146
|
+
const askAt = pendingAskIndex(msgs);
|
|
28
147
|
return (
|
|
29
148
|
<div className="space-y-4 px-3 py-4">
|
|
30
149
|
{msgs.map((m, i) => (
|
|
31
150
|
<MessageBubble
|
|
32
151
|
key={i}
|
|
33
152
|
msg={m}
|
|
34
|
-
|
|
153
|
+
askPending={i === askAt}
|
|
35
154
|
isAskAnswer={isAnswerToAsk(msgs, i)}
|
|
36
155
|
onCopy={onCopy}
|
|
156
|
+
onRegenerate={onRegenerate && m.role === "assistant" ? () => onRegenerate(i) : undefined}
|
|
157
|
+
onEdit={onEdit && m.role === "user" ? (text) => onEdit(i, text) : undefined}
|
|
158
|
+
compact={compact}
|
|
159
|
+
face={m.role === "assistant" ? faceFor?.(m) : undefined}
|
|
160
|
+
showSpeaker={showSpeaker}
|
|
161
|
+
nameOf={nameOf}
|
|
162
|
+
showTools={showTools}
|
|
37
163
|
/>
|
|
38
164
|
))}
|
|
39
|
-
|
|
165
|
+
{/* Waiting their turn, under the answer they will follow. Same bubble as
|
|
166
|
+
any other — what you wrote is in the conversation the moment you send
|
|
167
|
+
it, whether or not the agent has got to it yet. */}
|
|
168
|
+
{queued.map((q) => (
|
|
169
|
+
<MessageBubble
|
|
170
|
+
key={q.id}
|
|
171
|
+
msg={q.msg}
|
|
172
|
+
onCopy={onCopy}
|
|
173
|
+
compact={compact}
|
|
174
|
+
queued
|
|
175
|
+
onUnqueue={onUnqueue ? () => onUnqueue(q.id) : undefined}
|
|
176
|
+
showTools={showTools}
|
|
177
|
+
/>
|
|
178
|
+
))}
|
|
179
|
+
<div ref={bottomRef} style={bottomInset ? { height: bottomInset } : undefined} />
|
|
40
180
|
</div>
|
|
41
181
|
);
|
|
42
182
|
}
|
|
43
183
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
184
|
+
/** The nearest ancestor that actually scrolls. */
|
|
185
|
+
function scrollParentOf(el: HTMLElement): HTMLElement | null {
|
|
186
|
+
let p = el.parentElement;
|
|
187
|
+
while (p) {
|
|
188
|
+
const oy = getComputedStyle(p).overflowY;
|
|
189
|
+
if (oy === "auto" || oy === "scroll") return p;
|
|
190
|
+
p = p.parentElement;
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// A user message is an "ask answer" when an unanswered ask_questions call stood
|
|
196
|
+
// immediately before it — allowing for the line the agent says alongside its
|
|
197
|
+
// questions, which is a turn of its own and used to break the match. The
|
|
198
|
+
// InlineAskPanel compiles the user's picks into a single text reply, which we
|
|
199
|
+
// then render as a centered full-width card instead of the standard
|
|
200
|
+
// right-aligned user bubble.
|
|
48
201
|
function isAnswerToAsk(msgs: ChatMsg[], i: number): boolean {
|
|
49
202
|
const m = msgs[i];
|
|
50
203
|
if (!m || m.role !== "user") return false;
|
|
51
|
-
|
|
52
|
-
if (!prev || prev.role !== "assistant") return false;
|
|
53
|
-
for (let j = prev.parts.length - 1; j >= 0; j--) {
|
|
54
|
-
const p = prev.parts[j];
|
|
55
|
-
if (p.kind === "tool") return p.tool === "ask_questions";
|
|
56
|
-
}
|
|
57
|
-
return false;
|
|
204
|
+
return pendingAskIndex(msgs.slice(0, i)) >= 0;
|
|
58
205
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { Brain, ChevronRight, Loader2 } from "lucide-react";
|
|
3
|
+
import { cn } from "../../lib/cn";
|
|
4
|
+
import { t } from "../../i18n";
|
|
5
|
+
|
|
6
|
+
// The model thinking out loud, shown on purpose.
|
|
7
|
+
//
|
|
8
|
+
// It used to arrive spliced into the answer as `<think>…</think>` and render as
|
|
9
|
+
// part of the reply — the reader got the model's notes where the reply should
|
|
10
|
+
// be. The adapters now keep the two apart, which left the thinking with nowhere
|
|
11
|
+
// to go: correct, and invisible. This is where it goes.
|
|
12
|
+
//
|
|
13
|
+
// Open while it streams (that is the only moment it is worth watching, and it
|
|
14
|
+
// fills the wait before the first word of the answer), collapsed once the
|
|
15
|
+
// answer starts — unless the reader says otherwise, whose click wins from then
|
|
16
|
+
// on. Never a bubble: this is not something the agent said to you.
|
|
17
|
+
|
|
18
|
+
interface Props {
|
|
19
|
+
text: string;
|
|
20
|
+
/** Still being written. */
|
|
21
|
+
streaming?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function ReasoningBlock({ text, streaming }: Props) {
|
|
25
|
+
const [manual, setManual] = useState<boolean | null>(null);
|
|
26
|
+
const open = manual ?? !!streaming;
|
|
27
|
+
|
|
28
|
+
if (!text.trim()) return null;
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<div className="w-full overflow-hidden rounded-lg border border-border/60 bg-muted/10">
|
|
32
|
+
<button
|
|
33
|
+
type="button"
|
|
34
|
+
onClick={() => setManual(!open)}
|
|
35
|
+
aria-expanded={open}
|
|
36
|
+
className="flex w-full items-center gap-2 px-2.5 py-1.5 text-left text-[12px] text-muted-foreground"
|
|
37
|
+
>
|
|
38
|
+
<ChevronRight
|
|
39
|
+
className={cn("size-3 shrink-0 transition-transform", open && "rotate-90")}
|
|
40
|
+
/>
|
|
41
|
+
{streaming ? (
|
|
42
|
+
<Loader2 className="size-3.5 shrink-0 animate-spin text-violet-600 dark:text-violet-400" />
|
|
43
|
+
) : (
|
|
44
|
+
<Brain className="size-3.5 shrink-0" />
|
|
45
|
+
)}
|
|
46
|
+
<span className="font-medium">
|
|
47
|
+
{streaming ? t("chat_ui.thinking_running") : t("chat_ui.thinking_label")}
|
|
48
|
+
</span>
|
|
49
|
+
</button>
|
|
50
|
+
|
|
51
|
+
{open && (
|
|
52
|
+
<p className="whitespace-pre-wrap border-t border-border/50 px-2.5 py-2 text-[12px] leading-relaxed text-muted-foreground italic">
|
|
53
|
+
{text}
|
|
54
|
+
</p>
|
|
55
|
+
)}
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import useSWR from "swr";
|
|
3
|
+
import { ChevronDown } from "lucide-react";
|
|
4
|
+
import {
|
|
5
|
+
DropdownMenu,
|
|
6
|
+
DropdownMenuContent,
|
|
7
|
+
DropdownMenuGroup,
|
|
8
|
+
DropdownMenuItem,
|
|
9
|
+
DropdownMenuLabel,
|
|
10
|
+
DropdownMenuSeparator,
|
|
11
|
+
DropdownMenuTrigger,
|
|
12
|
+
} from "../ui/dropdown-menu";
|
|
13
|
+
import { Conversations } from "../../lib/api";
|
|
14
|
+
import { relativeWhen } from "../../lib/when";
|
|
15
|
+
import { cn } from "../../lib/cn";
|
|
16
|
+
import { t } from "../../i18n";
|
|
17
|
+
import type { ChatKey, ChatSelectionMeta } from "./ChatList";
|
|
18
|
+
|
|
19
|
+
/** Where a chat's sessions come from depends on who you are talking to: the
|
|
20
|
+
* super-agent has channel threads, a project agent has conversation files. */
|
|
21
|
+
export interface SessionRow {
|
|
22
|
+
key: ChatKey;
|
|
23
|
+
id: string;
|
|
24
|
+
label: string;
|
|
25
|
+
when: string;
|
|
26
|
+
channel?: string;
|
|
27
|
+
archived?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Every session of one chat, fetched only when someone asks to see them — the
|
|
32
|
+
* list is navigation, not something the chat needs in order to render.
|
|
33
|
+
*/
|
|
34
|
+
export function useSessionRows(
|
|
35
|
+
pid: string,
|
|
36
|
+
agentSlug: string,
|
|
37
|
+
isSuper: boolean,
|
|
38
|
+
enabled: boolean,
|
|
39
|
+
channelScope?: string,
|
|
40
|
+
) {
|
|
41
|
+
return useSWR<SessionRow[]>(
|
|
42
|
+
enabled ? `sessions:${pid}:${agentSlug}:${isSuper}:${channelScope ?? ""}` : null,
|
|
43
|
+
async () => {
|
|
44
|
+
// `channelScope` keeps this switcher in step with the surface it lives on:
|
|
45
|
+
// the inbox and the phone are web-only, so their session list must not
|
|
46
|
+
// offer a Telegram thread you'd never reach from there. Project-first
|
|
47
|
+
// navigation passes nothing and sees every channel.
|
|
48
|
+
const onScope = (ch?: string) => !channelScope || ch === channelScope;
|
|
49
|
+
// Archived ones are asked for HERE and nowhere else: this is the one
|
|
50
|
+
// list whose job is to offer every session back, including the ones put
|
|
51
|
+
// away. The sidebar and the inbox stay clear of them.
|
|
52
|
+
if (isSuper) {
|
|
53
|
+
const threads = await Conversations.threads(pid, true);
|
|
54
|
+
return threads
|
|
55
|
+
.filter((th) => onScope(th.channel))
|
|
56
|
+
.map((th) => ({
|
|
57
|
+
key: { kind: "thread", channel: th.channel, threadId: th.id } as ChatKey,
|
|
58
|
+
id: `${th.channel}:${th.id}`,
|
|
59
|
+
label: th.title || th.id,
|
|
60
|
+
when: th.last_ts || th.started_at || th.id,
|
|
61
|
+
channel: th.channel,
|
|
62
|
+
archived: th.archived,
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
const convs = await Conversations.list(pid, agentSlug, true);
|
|
66
|
+
return convs
|
|
67
|
+
.filter((c) => onScope(c.channel))
|
|
68
|
+
.map((c) => ({
|
|
69
|
+
key: { kind: "conv", agentSlug, convId: c.id } as ChatKey,
|
|
70
|
+
id: c.id,
|
|
71
|
+
label: c.title || c.id,
|
|
72
|
+
when: c.ended_at || c.started_at || c.id,
|
|
73
|
+
channel: c.channel,
|
|
74
|
+
archived: c.archived,
|
|
75
|
+
}));
|
|
76
|
+
},
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** The id of the session currently open, in the same spelling `SessionRow.id`
|
|
81
|
+
* uses — so the open one can be marked in the list. */
|
|
82
|
+
export function currentSessionId(selected: ChatKey): string {
|
|
83
|
+
if (selected.kind === "conv") return selected.convId;
|
|
84
|
+
if (selected.kind === "thread") return `${selected.channel}:${selected.threadId}`;
|
|
85
|
+
return "";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Which thread you are reading, and the way to any of the others.
|
|
90
|
+
*
|
|
91
|
+
* This is the line under the agent's name on every surface. It used to be flat
|
|
92
|
+
* text on the desktop — the date of the thread you were in, with no way to
|
|
93
|
+
* reach the rest without leaving for the sidebar, which the inbox does not
|
|
94
|
+
* have. One control, two frames: the phone shows it as the header's second
|
|
95
|
+
* line, the desktop as the header's subtitle.
|
|
96
|
+
*/
|
|
97
|
+
export function SessionPicker({
|
|
98
|
+
pid,
|
|
99
|
+
agentSlug,
|
|
100
|
+
isSuper,
|
|
101
|
+
selected,
|
|
102
|
+
label,
|
|
103
|
+
onPick,
|
|
104
|
+
className,
|
|
105
|
+
channelScope,
|
|
106
|
+
}: {
|
|
107
|
+
pid: string;
|
|
108
|
+
agentSlug: string;
|
|
109
|
+
isSuper: boolean;
|
|
110
|
+
selected: ChatKey;
|
|
111
|
+
/** What to show when closed — the thread's title, or "new session". */
|
|
112
|
+
label: string;
|
|
113
|
+
onPick: (key: ChatKey, meta?: ChatSelectionMeta) => void;
|
|
114
|
+
className?: string;
|
|
115
|
+
/** Limit the list to one channel (the inbox and the phone pass "web"). */
|
|
116
|
+
channelScope?: string;
|
|
117
|
+
}) {
|
|
118
|
+
const current = currentSessionId(selected);
|
|
119
|
+
// `useSWR(null)` is the off switch: the list is fetched the moment someone
|
|
120
|
+
// reaches for it, not on every chat that gets opened. Armed on hover/focus so
|
|
121
|
+
// it is already there by the time the menu paints.
|
|
122
|
+
const [armed, setArmed] = useState(false);
|
|
123
|
+
const sessions = useSessionRows(pid, agentSlug, isSuper, armed, channelScope);
|
|
124
|
+
const rows = sessions.data || [];
|
|
125
|
+
const live = rows.filter((s) => !s.archived);
|
|
126
|
+
const archivedRows = rows.filter((s) => s.archived);
|
|
127
|
+
|
|
128
|
+
const renderRow = (s: SessionRow) => (
|
|
129
|
+
<DropdownMenuItem
|
|
130
|
+
key={s.id}
|
|
131
|
+
onClick={() => onPick(s.key, { archived: s.archived, title: s.label, channel: s.channel })}
|
|
132
|
+
className={cn("items-start gap-2", s.id === current && "bg-primary/10", s.archived && "opacity-70")}
|
|
133
|
+
>
|
|
134
|
+
<span className="min-w-0 flex-1">
|
|
135
|
+
<span className="block truncate text-[13px]">{s.label}</span>
|
|
136
|
+
{s.channel && <span className="text-[10px] text-muted-fg">{s.channel}</span>}
|
|
137
|
+
</span>
|
|
138
|
+
<span className="shrink-0 text-[10px] text-muted-fg">{relativeWhen(s.when, t as never)}</span>
|
|
139
|
+
</DropdownMenuItem>
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<DropdownMenu>
|
|
144
|
+
<DropdownMenuTrigger
|
|
145
|
+
className={cn(
|
|
146
|
+
"flex min-w-0 max-w-full items-center gap-1 text-[11px] text-muted-fg hover:text-foreground",
|
|
147
|
+
className,
|
|
148
|
+
)}
|
|
149
|
+
aria-label={t("mobile.sessions")}
|
|
150
|
+
onPointerEnter={() => setArmed(true)}
|
|
151
|
+
onFocus={() => setArmed(true)}
|
|
152
|
+
onClick={() => setArmed(true)}
|
|
153
|
+
>
|
|
154
|
+
<span className="truncate">{label}</span>
|
|
155
|
+
<ChevronDown size={12} className="shrink-0 transition-transform data-[popup-open]:rotate-180" />
|
|
156
|
+
</DropdownMenuTrigger>
|
|
157
|
+
<DropdownMenuContent align="start" sideOffset={6} className="max-h-[60vh] w-72 overflow-y-auto">
|
|
158
|
+
{sessions.isLoading && (
|
|
159
|
+
<p className="px-2 py-2 text-sm text-muted-fg">{t("common.loading")}</p>
|
|
160
|
+
)}
|
|
161
|
+
{live.map(renderRow)}
|
|
162
|
+
{/* Put away, not gone. They sit under their own heading at the bottom so
|
|
163
|
+
the list stays about what you are likely to resume, while the way
|
|
164
|
+
back to an archived thread is still one scroll away. */}
|
|
165
|
+
{archivedRows.length > 0 && (
|
|
166
|
+
<>
|
|
167
|
+
<DropdownMenuSeparator />
|
|
168
|
+
<DropdownMenuGroup>
|
|
169
|
+
<DropdownMenuLabel className="text-[10px] uppercase tracking-wide text-muted-fg">
|
|
170
|
+
{t("project.chat.archived_group")}
|
|
171
|
+
</DropdownMenuLabel>
|
|
172
|
+
</DropdownMenuGroup>
|
|
173
|
+
{archivedRows.map(renderRow)}
|
|
174
|
+
</>
|
|
175
|
+
)}
|
|
176
|
+
{sessions.data && !sessions.data.length && (
|
|
177
|
+
<p className="px-2 py-2 text-sm text-muted-fg">{t("mobile.no_sessions")}</p>
|
|
178
|
+
)}
|
|
179
|
+
</DropdownMenuContent>
|
|
180
|
+
</DropdownMenu>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import useSWR from "swr";
|
|
2
|
+
import { ArrowUpRight, Sparkles } from "lucide-react";
|
|
3
|
+
import { useLocation, useNavigate } from "react-router-dom";
|
|
4
|
+
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
|
5
|
+
import { Tip } from "../ui/tip";
|
|
6
|
+
import { Badge } from "../ui";
|
|
7
|
+
import { Skills } from "../../lib/api";
|
|
8
|
+
import { useProject } from "../../hooks/useProjects";
|
|
9
|
+
import { t } from "../../i18n";
|
|
10
|
+
|
|
11
|
+
export type InspectorTrace = {
|
|
12
|
+
embedder?: string;
|
|
13
|
+
/** Bodies inlined into this turn's system prompt. */
|
|
14
|
+
loaded?: string[];
|
|
15
|
+
/** Only the slug + one-line description made it in. */
|
|
16
|
+
hinted?: string[];
|
|
17
|
+
/** Top matches with their cosine similarity, when the stream carried them. */
|
|
18
|
+
scored?: { slug: string; sim: number }[];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The row of skill badges under an assistant turn: what the per-turn RAG put
|
|
23
|
+
* in the prompt. Each badge opens a card explaining what it cost the context
|
|
24
|
+
* (whole body vs. one line) and links to the skill itself — the badge names a
|
|
25
|
+
* thing you own, so it has to be reachable from where it is named.
|
|
26
|
+
*/
|
|
27
|
+
// How much of a near-miss is worth showing as "considered". The offline `tf`
|
|
28
|
+
// fallback embedder scores everything low and compressed — an on-topic postbean
|
|
29
|
+
// query lands around 0.18-0.28 — so the calibrated 0.40 hint bar hides even a
|
|
30
|
+
// clearly relevant match. This low floor keeps those visible; it can't fully
|
|
31
|
+
// separate signal from noise on `tf` (that needs a real embedder — ollama/
|
|
32
|
+
// gemini), but it makes each round's top matches legible instead of silent.
|
|
33
|
+
const CONSIDERED_MIN_SIM = 0.15;
|
|
34
|
+
const MAX_CONSIDERED = 3;
|
|
35
|
+
|
|
36
|
+
type BadgeVariant = "loaded" | "hint" | "considered";
|
|
37
|
+
|
|
38
|
+
export function SkillTrace({ inspector }: { inspector: InspectorTrace }) {
|
|
39
|
+
const loaded = inspector.loaded || [];
|
|
40
|
+
const hinted = inspector.hinted || [];
|
|
41
|
+
// Near-misses: top scored matches that were neither loaded nor hinted. Shown
|
|
42
|
+
// dimmer so the per-turn RAG is legible every round — you can see what it
|
|
43
|
+
// weighed, not only what it injected.
|
|
44
|
+
const injected = new Set([...loaded, ...hinted]);
|
|
45
|
+
const considered = (inspector.scored || [])
|
|
46
|
+
.filter((s) => !injected.has(s.slug) && s.sim >= CONSIDERED_MIN_SIM)
|
|
47
|
+
.slice(0, MAX_CONSIDERED)
|
|
48
|
+
.map((s) => s.slug);
|
|
49
|
+
|
|
50
|
+
if (loaded.length === 0 && hinted.length === 0 && considered.length === 0) return null;
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<div className="flex flex-wrap items-center gap-1 text-[10px] text-sky-700 dark:text-sky-400/90">
|
|
54
|
+
<Tip content={t("shared_ui.skill_inspector_title", { embedder: inspector.embedder || "RAG" })}>
|
|
55
|
+
<span className="grid size-3.5 place-items-center">
|
|
56
|
+
<Sparkles size={10} />
|
|
57
|
+
</span>
|
|
58
|
+
</Tip>
|
|
59
|
+
{loaded.map((slug) => (
|
|
60
|
+
<SkillBadge key={`l-${slug}`} slug={slug} variant="loaded" inspector={inspector} />
|
|
61
|
+
))}
|
|
62
|
+
{hinted.map((slug) => (
|
|
63
|
+
<SkillBadge key={`h-${slug}`} slug={slug} variant="hint" inspector={inspector} />
|
|
64
|
+
))}
|
|
65
|
+
{considered.map((slug) => (
|
|
66
|
+
<SkillBadge key={`c-${slug}`} slug={slug} variant="considered" inspector={inspector} />
|
|
67
|
+
))}
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const BADGE_CLASS: Record<BadgeVariant, string> = {
|
|
73
|
+
loaded: "cursor-pointer rounded bg-sky-500/15 px-1 py-0.5 font-mono hover:bg-sky-500/25",
|
|
74
|
+
hint: "cursor-pointer rounded border border-sky-500/30 px-1 py-0.5 font-mono opacity-70 hover:opacity-100",
|
|
75
|
+
considered:
|
|
76
|
+
"cursor-pointer rounded border border-dashed border-sky-500/25 px-1 py-0.5 font-mono opacity-50 hover:opacity-90",
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
function SkillBadge({
|
|
80
|
+
slug,
|
|
81
|
+
variant,
|
|
82
|
+
inspector,
|
|
83
|
+
}: {
|
|
84
|
+
slug: string;
|
|
85
|
+
variant: BadgeVariant;
|
|
86
|
+
inspector: InspectorTrace;
|
|
87
|
+
}) {
|
|
88
|
+
const label = variant === "loaded" ? slug : variant === "hint" ? `${slug}?` : `~${slug}`;
|
|
89
|
+
return (
|
|
90
|
+
<Popover>
|
|
91
|
+
<PopoverTrigger className={BADGE_CLASS[variant]}>{label}</PopoverTrigger>
|
|
92
|
+
<PopoverContent>
|
|
93
|
+
<SkillCard slug={slug} variant={variant} inspector={inspector} />
|
|
94
|
+
</PopoverContent>
|
|
95
|
+
</Popover>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Rendered only once the popover opens (Base UI mounts the portal on demand),
|
|
100
|
+
// so the catalog is fetched on the first click, not on every message painted.
|
|
101
|
+
function SkillCard({
|
|
102
|
+
slug,
|
|
103
|
+
variant,
|
|
104
|
+
inspector,
|
|
105
|
+
}: {
|
|
106
|
+
slug: string;
|
|
107
|
+
variant: BadgeVariant;
|
|
108
|
+
inspector: InspectorTrace;
|
|
109
|
+
}) {
|
|
110
|
+
const navigate = useNavigate();
|
|
111
|
+
const pid = usePidFromRoute();
|
|
112
|
+
const { project } = useProject(pid);
|
|
113
|
+
const projectPath = pid === "0" ? undefined : project?.path;
|
|
114
|
+
const ready = pid === "0" || !!projectPath;
|
|
115
|
+
|
|
116
|
+
// Same SWR key the composer's `/slug` picker uses — usually a cache hit.
|
|
117
|
+
const { data } = useSWR(ready ? ["/api/skills", projectPath || ""] : null, () =>
|
|
118
|
+
Skills.list(projectPath),
|
|
119
|
+
);
|
|
120
|
+
const entry = data?.skills.find((s) => s.slug === slug);
|
|
121
|
+
const sim = inspector.scored?.find((s) => s.slug === slug)?.sim;
|
|
122
|
+
|
|
123
|
+
const open = () => {
|
|
124
|
+
// Inside the Roby sheet the chat sits on top of the router: navigating
|
|
125
|
+
// alone would land behind it. The sheet closes itself on this event.
|
|
126
|
+
window.dispatchEvent(new CustomEvent("apx:roby-close"));
|
|
127
|
+
navigate(`/p/${pid}/skills?skill=${encodeURIComponent(slug)}`);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<div className="flex flex-col gap-2 text-foreground">
|
|
132
|
+
<div className="flex items-start justify-between gap-2">
|
|
133
|
+
<code className="font-mono text-xs font-semibold">{slug}</code>
|
|
134
|
+
{entry && <Badge tone={sourceTone(entry.source)}>{sourceLabel(entry.source)}</Badge>}
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<p className="text-[11px] text-muted-foreground">
|
|
138
|
+
{variant === "loaded"
|
|
139
|
+
? t("shared_ui.skill_trace_loaded")
|
|
140
|
+
: variant === "hint"
|
|
141
|
+
? t("shared_ui.skill_trace_hinted")
|
|
142
|
+
: t("shared_ui.skill_trace_considered")}
|
|
143
|
+
{typeof sim === "number" && ` · ${t("shared_ui.skill_trace_sim", { sim: sim.toFixed(2) })}`}
|
|
144
|
+
</p>
|
|
145
|
+
|
|
146
|
+
<p className="text-xs leading-relaxed">
|
|
147
|
+
{entry?.description || t("shared_ui.skill_trace_no_desc")}
|
|
148
|
+
</p>
|
|
149
|
+
|
|
150
|
+
<button
|
|
151
|
+
type="button"
|
|
152
|
+
onClick={open}
|
|
153
|
+
className="flex items-center gap-1 self-start text-xs font-medium text-sky-700 hover:underline dark:text-sky-400"
|
|
154
|
+
>
|
|
155
|
+
{t("shared_ui.skill_trace_open")} <ArrowUpRight size={12} />
|
|
156
|
+
</button>
|
|
157
|
+
</div>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Which project's skills screen the badge should open: the one you are in,
|
|
162
|
+
* the base project (the super-agent's own scope) anywhere else. */
|
|
163
|
+
function usePidFromRoute(): string {
|
|
164
|
+
const { pathname } = useLocation();
|
|
165
|
+
return pathname.match(/^\/p\/([^/]+)/)?.[1] ?? "0";
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function sourceLabel(source: string, origin?: string | null): string {
|
|
169
|
+
const host = origin || source;
|
|
170
|
+
if (source === "builtin" || host === "apx" || host === "builtin") return t("skills_page.source_builtin");
|
|
171
|
+
if (source === "project" || host === "project") return t("skills_page.source_project");
|
|
172
|
+
if (host === "claude") return t("skills_page.origin_claude");
|
|
173
|
+
if (host === "cursor") return t("skills_page.origin_cursor");
|
|
174
|
+
if (host === "codex") return t("skills_page.origin_codex");
|
|
175
|
+
if (host === "agents") return t("skills_page.origin_agents");
|
|
176
|
+
return t("skills_page.source_global");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function sourceTone(source: string): "info" | "success" | "muted" {
|
|
180
|
+
if (source === "builtin") return "info";
|
|
181
|
+
if (source === "project") return "success";
|
|
182
|
+
return "muted";
|
|
183
|
+
}
|