@agentprojectcontext/apx 1.80.2 → 1.89.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -8
- package/skills/apc-context/SKILL.md +14 -7
- package/skills/apx/SKILL.md +62 -2
- package/skills/apx-mcp/SKILL.md +42 -15
- package/src/core/agent/a2a/peers.js +161 -0
- package/src/core/agent/a2a/reply.js +379 -27
- package/src/core/agent/abort.js +25 -0
- package/src/core/agent/agent-model.js +58 -0
- package/src/core/agent/agent-tools.js +101 -0
- package/src/core/agent/author-line.js +110 -0
- package/src/core/agent/build-agent-system.js +52 -18
- package/src/core/agent/channels/voice-context.js +17 -2
- package/src/core/agent/closing-floor.js +117 -0
- package/src/core/agent/constants.js +119 -11
- package/src/core/agent/engine-call.js +56 -0
- package/src/core/agent/group/run-group-turn.js +218 -0
- package/src/core/agent/group/turn-resolver.js +165 -0
- package/src/core/agent/judge.js +138 -11
- package/src/core/agent/loop/side-effects.js +106 -3
- package/src/core/agent/memory.js +31 -18
- package/src/core/agent/model-capabilities.js +47 -0
- package/src/core/agent/model-router.js +11 -40
- package/src/core/agent/prompt-builder.js +47 -0
- package/src/core/agent/prompts/channels/a2a.md +12 -0
- package/src/core/agent/prompts/channels/code.md +3 -1
- package/src/core/agent/prompts/channels/telegram.md +2 -0
- package/src/core/agent/prompts/channels/web_code.md +1 -1
- package/src/core/agent/prompts/channels/whatsapp.md +37 -0
- package/src/core/agent/prompts/core/agent-base.md +2 -0
- package/src/core/agent/prompts/discipline/action.md +1 -0
- package/src/core/agent/prompts/discipline/two-segment.md +2 -1
- package/src/core/agent/prompts/modes/mobility.md +36 -0
- package/src/core/agent/retry.js +42 -0
- package/src/core/agent/run-agent.js +322 -25
- package/src/core/agent/run-turn.js +253 -0
- package/src/core/agent/self-memory.js +18 -52
- package/src/core/agent/skills/agent-skills.js +118 -0
- package/src/core/agent/skills/catalog.js +1 -1
- package/src/core/agent/skills/declared.js +13 -0
- package/src/core/agent/skills/index-store.js +8 -1
- package/src/core/agent/skills/inspector.js +20 -3
- package/src/core/agent/skills/loader.js +18 -3
- package/src/core/agent/skills/media.js +121 -0
- package/src/core/agent/skills/origin.js +61 -0
- package/src/core/agent/skills/sections.js +136 -0
- package/src/core/agent/super-agent.js +54 -14
- package/src/core/agent/tools/handlers/_calendar.js +50 -0
- package/src/core/agent/tools/handlers/add-mcp.js +103 -0
- package/src/core/agent/tools/handlers/asana-create-task.js +3 -1
- package/src/core/agent/tools/handlers/attach-media.js +56 -0
- package/src/core/agent/tools/handlers/calendar-create-event.js +38 -0
- package/src/core/agent/tools/handlers/calendar-find-slot.js +39 -0
- package/src/core/agent/tools/handlers/calendar-list-events.js +39 -0
- package/src/core/agent/tools/handlers/calendar-update-event.js +35 -0
- package/src/core/agent/tools/handlers/call-agent.js +14 -6
- package/src/core/agent/tools/handlers/call-runtime.js +27 -49
- package/src/core/agent/tools/handlers/comment-task.js +78 -0
- package/src/core/agent/tools/handlers/complete-task.js +60 -0
- package/src/core/agent/tools/handlers/configure-agent.js +70 -0
- package/src/core/agent/tools/handlers/create-agent.js +68 -0
- package/src/core/agent/tools/handlers/create-task.js +41 -3
- package/src/core/agent/tools/handlers/import-agent.js +5 -5
- package/src/core/agent/tools/handlers/list-mcp-tools.js +83 -0
- package/src/core/agent/tools/handlers/list-routines.js +46 -0
- package/src/core/agent/tools/handlers/list-tasks.js +8 -1
- package/src/core/agent/tools/handlers/mark-commitment.js +57 -0
- package/src/core/agent/tools/handlers/read-skill.js +64 -0
- package/src/core/agent/tools/handlers/remember-routine.js +2 -8
- package/src/core/agent/tools/handlers/remember.js +82 -6
- package/src/core/agent/tools/handlers/remove-agent.js +42 -0
- package/src/core/agent/tools/handlers/run-routine.js +94 -0
- package/src/core/agent/tools/handlers/run-shell.js +44 -2
- package/src/core/agent/tools/handlers/send-telegram.js +41 -19
- package/src/core/agent/tools/handlers/set-agent-prompt.js +44 -0
- package/src/core/agent/tools/handlers/view-media.js +69 -0
- package/src/core/agent/tools/handlers/write-agent-memory.js +52 -0
- package/src/core/agent/tools/helpers.js +36 -4
- package/src/core/agent/tools/names.js +64 -0
- package/src/core/agent/tools/registry-bridge.js +24 -1
- package/src/core/agent/tools/registry.js +79 -0
- package/src/core/agent/tools/tool-call-parser.js +136 -13
- package/src/core/agent/vision-bridge.js +69 -0
- package/src/core/apc/agent-identity.js +74 -0
- package/src/core/apc/agent-rename-refs.js +187 -0
- package/src/core/apc/agent-write.js +312 -0
- package/src/core/apc/agents-vault.js +1 -1
- package/src/core/apc/blob-keys.js +42 -0
- package/src/core/apc/frontmatter.js +166 -10
- package/src/core/apc/parser.js +33 -83
- package/src/core/apc/paths.js +4 -6
- package/src/core/apc/project-memory.js +44 -0
- package/src/core/apc/projects-helpers.js +33 -0
- package/src/core/apc/scaffold.js +36 -16
- package/src/core/channels/telegram/ask-callbacks.js +103 -0
- package/src/core/channels/telegram/dispatch.js +154 -30
- package/src/core/channels/telegram/helpers.js +59 -7
- package/src/core/channels/telegram/inbound/audio.js +26 -30
- package/src/core/channels/telegram/inbound/file.js +22 -32
- package/src/core/channels/telegram/inbound/photo.js +24 -28
- package/src/core/channels/telegram/progress-gate.js +76 -0
- package/src/core/channels/telegram/reply.js +151 -43
- package/src/core/channels/telegram/voice-note.js +150 -0
- package/src/core/config/index.js +53 -54
- package/src/core/config/paths.js +117 -31
- package/src/core/config/redact.js +89 -4
- package/src/core/config/secret-values.js +2 -4
- package/src/core/constants/actors.js +5 -0
- package/src/core/constants/channels.js +3 -1
- package/src/core/constants/task-categories.js +73 -0
- package/src/core/constants/task-fields.js +28 -0
- package/src/core/engines/_globs.js +33 -0
- package/src/core/engines/anthropic.js +19 -1
- package/src/core/engines/catalog.js +20 -0
- package/src/core/engines/gemini.js +84 -16
- package/src/core/engines/index.js +19 -3
- package/src/core/engines/mock.js +145 -1
- package/src/core/engines/openai-compatible.js +150 -15
- package/src/core/engines/presets.js +36 -9
- package/src/core/engines/zen.js +131 -0
- package/src/core/events/bus.js +140 -0
- package/src/core/events/mascot-notify.js +156 -0
- package/src/core/http-tools/browser.js +366 -36
- package/src/core/http-tools/catalog.js +206 -22
- package/src/core/http-tools/grep.js +62 -7
- package/src/core/http-tools/registry.js +3 -1
- package/src/core/i18n/en.js +34 -3
- package/src/core/i18n/es.js +36 -4
- package/src/core/i18n/index.js +5 -5
- package/src/core/i18n/pt.js +32 -3
- package/src/core/identity/self.js +14 -1
- package/src/core/images/engines/a1111.js +219 -0
- package/src/core/images/engines/index.js +187 -0
- package/src/core/images/engines/mock.js +74 -0
- package/src/core/images/engines/openai.js +130 -0
- package/src/core/images/engines/sdcpp.js +204 -0
- package/src/core/images/engines/shared.js +218 -0
- package/src/core/images/generate.js +260 -0
- package/src/core/integrations/catalog.js +8 -3
- package/src/core/integrations/plugins/_google-oauth.js +179 -0
- package/src/core/integrations/plugins/asana.js +7 -3
- package/src/core/integrations/plugins/calendar.js +404 -0
- package/src/core/integrations/store.js +2 -0
- package/src/core/memory/broker.js +16 -1
- package/src/core/memory/compactor.js +19 -3
- package/src/core/memory/consolidate.js +2 -2
- package/src/core/memory/dated-log.js +66 -0
- package/src/core/memory/embed-engines/custom.js +59 -0
- package/src/core/memory/embed-engines/gemini.js +9 -3
- package/src/core/memory/embed-engines/index.js +87 -15
- package/src/core/memory/embeddings.js +52 -24
- package/src/core/memory/index.js +13 -3
- package/src/core/memory/indexer.js +83 -27
- package/src/core/memory/prune.js +182 -0
- package/src/core/memory/store.js +22 -0
- package/src/core/memory/summarizer.js +72 -8
- package/src/core/mobility/answer.js +80 -0
- package/src/core/mobility/geofence.js +667 -0
- package/src/core/mobility/osm-route.js +282 -0
- package/src/core/mobility/preferences.js +91 -0
- package/src/core/mobility/state.js +245 -0
- package/src/core/mobility/trip-event.js +384 -0
- package/src/core/net/tailscale.js +168 -0
- package/src/core/profiles/bundled/secretary/PROFILE.md +32 -42
- package/src/core/profiles/bundled/secretary/config.schema.es.json +68 -0
- package/src/core/profiles/bundled/secretary/config.schema.json +30 -2
- package/src/core/profiles/bundled/secretary/profile.json +3 -1
- package/src/core/profiles/bundled/secretary/routines/a2a-sweep.json +20 -0
- package/src/core/profiles/bundled/secretary/routines/day-close.json +4 -1
- package/src/core/profiles/bundled/secretary/routines/day-open.json +7 -1
- package/src/core/profiles/bundled/secretary/routines/watch.json +13 -2
- package/src/core/profiles/lifecycle.js +243 -19
- package/src/core/profiles/paths.js +12 -0
- package/src/core/profiles/store.js +47 -0
- package/src/core/routines/active-runs.js +213 -0
- package/src/core/routines/delivery.js +612 -0
- package/src/core/routines/header.js +88 -0
- package/src/core/routines/index.js +26 -0
- package/src/core/routines/run-log.js +78 -0
- package/src/core/routines/runner.js +629 -66
- package/src/core/routines/signals.js +75 -0
- package/src/core/runtime-skills/apc-context/SKILL.md +14 -7
- package/src/core/runtime-skills/apx/SKILL.md +93 -1
- package/src/core/runtime-skills/apx-agency-agents/SKILL.md +2 -2
- package/src/core/runtime-skills/apx-agent/SKILL.md +134 -19
- package/src/core/runtime-skills/apx-commitment/SKILL.md +134 -0
- package/src/core/runtime-skills/apx-image/SKILL.md +60 -0
- package/src/core/runtime-skills/apx-integrations/SKILL.md +82 -0
- package/src/core/runtime-skills/apx-mcp/SKILL.md +45 -14
- package/src/core/runtime-skills/apx-mcp-builder/SKILL.md +4 -4
- package/src/core/runtime-skills/apx-profile/SKILL.md +27 -2
- package/src/core/runtime-skills/apx-project/SKILL.md +23 -2
- package/src/core/runtime-skills/apx-routine/SKILL.md +40 -17
- package/src/core/runtime-skills/apx-runtime/SKILL.md +124 -14
- package/src/core/runtime-skills/apx-sessions/SKILL.md +7 -6
- package/src/core/runtime-skills/apx-skill-builder/SKILL.md +15 -13
- package/src/core/runtime-skills/apx-task/SKILL.md +79 -26
- package/src/core/runtime-skills/apx-telegram/SKILL.md +12 -12
- package/src/core/runtime-skills/apx-transcribe/SKILL.md +56 -0
- package/src/core/runtime-skills/apx-voice/SKILL.md +27 -8
- package/src/core/runtime-skills/claude-code/SKILL.md +8 -0
- package/src/core/runtime-skills/openrouter/SKILL.md +8 -2
- package/src/core/runtimes/_spawn.js +9 -1
- package/src/core/runtimes/claude-code.js +11 -2
- package/src/core/runtimes/codex.js +44 -10
- package/src/core/runtimes/index.js +17 -2
- package/src/core/runtimes/opencode.js +88 -9
- package/src/core/runtimes/outcome.js +119 -0
- package/src/core/sessions/index.js +193 -1
- package/src/core/stores/agent-inbox.js +109 -23
- package/src/core/stores/code-sessions.js +21 -0
- package/src/core/stores/commitments.js +27 -3
- package/src/core/stores/conversations.js +220 -20
- package/src/core/stores/deliveries.js +177 -0
- package/src/core/stores/media-archive.js +228 -0
- package/src/core/stores/messages.js +1096 -112
- package/src/core/stores/organization.js +34 -0
- package/src/core/stores/project-memory.js +71 -0
- package/src/core/stores/routine-memory.js +16 -8
- package/src/core/stores/routines.js +27 -49
- package/src/core/stores/sessions.js +4 -8
- package/src/core/stores/tasks.js +212 -18
- package/src/core/stores/turn-record.js +209 -0
- package/src/core/tasks/columns.js +136 -0
- package/src/core/tasks/comment-turn.js +258 -0
- package/src/core/util/time.js +13 -0
- package/src/core/voice/engines/index.js +54 -1
- package/src/core/voice/engines/openai.js +50 -4
- package/src/core/voice/opus.js +67 -0
- package/src/core/voice/pronounceable.js +43 -0
- package/src/core/voice/transcription.js +4 -0
- package/src/core/voice/tts.js +114 -24
- package/src/host/daemon/active-turns.js +188 -0
- package/src/host/daemon/api/admin-config.js +9 -0
- package/src/host/daemon/api/agents.js +99 -90
- package/src/host/daemon/api/artifact-preview.js +7 -6
- package/src/host/daemon/api/artifacts.js +3 -2
- package/src/host/daemon/api/code.js +55 -9
- package/src/host/daemon/api/commitments.js +11 -0
- package/src/host/daemon/api/confirm.js +3 -2
- package/src/host/daemon/api/conversations.js +543 -35
- package/src/host/daemon/api/deck.js +9 -8
- package/src/host/daemon/api/deliveries.js +33 -0
- package/src/host/daemon/api/desktop.js +5 -4
- package/src/host/daemon/api/embeddings.js +15 -6
- package/src/host/daemon/api/engines.js +59 -8
- package/src/host/daemon/api/exec.js +437 -121
- package/src/host/daemon/api/groups.js +215 -0
- package/src/host/daemon/api/images.js +107 -0
- package/src/host/daemon/api/inbox.js +123 -2
- package/src/host/daemon/api/integrations.js +64 -2
- package/src/host/daemon/api/mcps.js +7 -6
- package/src/host/daemon/api/media.js +283 -0
- package/src/host/daemon/api/mobility.js +177 -0
- package/src/host/daemon/api/net.js +182 -0
- package/src/host/daemon/api/pairing.js +38 -5
- package/src/host/daemon/api/profiles.js +30 -2
- package/src/host/daemon/api/routines.js +36 -4
- package/src/host/daemon/api/runtimes.js +74 -39
- package/src/host/daemon/api/sessions-search.js +7 -2
- package/src/host/daemon/api/sessions.js +44 -2
- package/src/host/daemon/api/shared.js +127 -20
- package/src/host/daemon/api/skills.js +11 -4
- package/src/host/daemon/api/super-agent.js +384 -53
- package/src/host/daemon/api/tasks.js +180 -10
- package/src/host/daemon/api/telegram.js +11 -10
- package/src/host/daemon/api/thread-faces.js +159 -0
- package/src/host/daemon/api/top-level.js +3 -3
- package/src/host/daemon/api/transcribe.js +11 -10
- package/src/host/daemon/api/tts.js +97 -4
- package/src/host/daemon/api/turn-abort.js +23 -0
- package/src/host/daemon/api/turns.js +49 -0
- package/src/host/daemon/api/voice.js +5 -4
- package/src/host/daemon/api/web.js +98 -0
- package/src/host/daemon/api.js +39 -0
- package/src/host/daemon/delivery-sweep.js +58 -0
- package/src/host/daemon/desktop-ws.js +5 -23
- package/src/host/daemon/events-ws.js +273 -0
- package/src/host/daemon/index.js +59 -15
- package/src/host/daemon/plugins/desktop/index.js +17 -4
- package/src/host/daemon/plugins/telegram/index.js +78 -40
- package/src/host/daemon/pty-bridge.py +99 -0
- package/src/host/daemon/routines-scheduler.js +1 -0
- package/src/host/daemon/smoke.js +1 -2
- package/src/host/daemon/terminal-ws.js +132 -0
- package/src/host/daemon/tts-keepwarm.js +87 -0
- package/src/host/daemon/wakeup.js +11 -6
- package/src/host/daemon/whisper-server.js +44 -0
- package/src/host/daemon/whisper-server.py +70 -13
- package/src/host/daemon/ws-auth.js +28 -0
- package/src/interfaces/android/app/build.gradle +42 -0
- package/src/interfaces/android/app/proguard-rules.pro +4 -0
- package/src/interfaces/android/app/src/main/AndroidManifest.xml +139 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AlertScreen.java +139 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AndroidAutoDetector.java +106 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxCarAppService.java +57 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxPreferences.java +165 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarAlertStore.java +84 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageActionReceiver.java +47 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageNotification.java +152 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonAddress.java +35 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonClient.java +339 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DeviceLocation.java +38 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ErrandScreen.java +127 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MainActivity.java +872 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationDetector.java +63 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationListenerService.java +453 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsShareIntentParser.java +93 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotBlobCatalog.java +66 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotOverlayService.java +448 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotView.java +249 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MessageFrameParser.java +240 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/NotifyChannels.java +69 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityActionReceiver.java +78 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityNotification.java +161 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/StartupReceiver.java +57 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelEventGate.java +62 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelStatusBanner.java +116 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripLocationService.java +272 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripPlacesSheet.java +203 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripScreen.java +182 -0
- package/src/interfaces/android/app/src/main/res/drawable/app_background.xml +12 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_app.xml +10 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_launcher_foreground.xml +12 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_notification.xml +22 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_trip_car.xml +37 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/apx_logo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_amatista.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_aqua.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_brasa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_campana.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_caracol.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_carbon.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cobalto.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cometa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_coral.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cubi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_eclipse.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_faro.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_gajo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_iris.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_kiwi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_laguna.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_lila.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_menta.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_nimbo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_noche.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_onyx.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_orbita.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_ovni.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_papa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_parche.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_peon.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_perla.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_pino.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_quad.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_rubi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_saturno.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trebol.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trino.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_volcan.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_zafiro.png +0 -0
- package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
- package/src/interfaces/android/app/src/main/res/raw/apx_notification.mp3 +0 -0
- package/src/interfaces/android/app/src/main/res/values/colors.xml +4 -0
- package/src/interfaces/android/app/src/main/res/values/strings.xml +25 -0
- package/src/interfaces/android/app/src/main/res/values/styles.xml +10 -0
- package/src/interfaces/android/app/src/main/res/values-v31/styles.xml +14 -0
- package/src/interfaces/android/app/src/main/res/xml/automotive_app_desc.xml +9 -0
- package/src/interfaces/android/app/src/main/res/xml/network_security_config.xml +10 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/AndroidAutoDetectorTest.java +85 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/CarAlertStoreTest.java +104 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/DaemonAddressTest.java +23 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsNavigationDetectorTest.java +69 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsShareIntentParserTest.java +31 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MessageFrameParserTest.java +180 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TravelEventGateTest.java +64 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TripPlacesSheetTest.java +66 -0
- package/src/interfaces/android/build.gradle +3 -0
- package/src/interfaces/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/src/interfaces/android/gradle/wrapper/gradle-wrapper.properties +9 -0
- package/src/interfaces/android/gradle.properties +3 -0
- package/src/interfaces/android/gradlew +248 -0
- package/src/interfaces/android/gradlew.bat +82 -0
- package/src/interfaces/android/settings.gradle +18 -0
- package/src/interfaces/cli/commands/a2a.js +145 -4
- package/src/interfaces/cli/commands/agent.js +247 -22
- package/src/interfaces/cli/commands/code.js +1 -1
- package/src/interfaces/cli/commands/commitment.js +5 -0
- package/src/interfaces/cli/commands/config.js +85 -6
- package/src/interfaces/cli/commands/exec.js +90 -1
- package/src/interfaces/cli/commands/image.js +314 -0
- package/src/interfaces/cli/commands/mcp.js +87 -23
- package/src/interfaces/cli/commands/memory.js +35 -22
- package/src/interfaces/cli/commands/panel.js +94 -0
- package/src/interfaces/cli/commands/profile.js +14 -0
- package/src/interfaces/cli/commands/project.js +29 -0
- package/src/interfaces/cli/commands/routine.js +45 -10
- package/src/interfaces/cli/commands/runtime.js +30 -7
- package/src/interfaces/cli/commands/session.js +90 -38
- package/src/interfaces/cli/commands/sessions.js +35 -2
- package/src/interfaces/cli/commands/skills.js +15 -9
- package/src/interfaces/cli/commands/status.js +2 -3
- package/src/interfaces/cli/commands/task.js +54 -5
- package/src/interfaces/cli/commands/telegram.js +12 -4
- package/src/interfaces/cli/commands/transcribe.js +177 -0
- package/src/interfaces/cli/help/index.js +311 -72
- package/src/interfaces/cli/http.js +61 -13
- package/src/interfaces/cli/index.js +1 -1
- package/src/interfaces/cli/routes/agent.js +5 -4
- package/src/interfaces/cli/routes/commitment.js +3 -2
- package/src/interfaces/cli/routes/config.js +7 -2
- package/src/interfaces/cli/routes/image.js +11 -0
- package/src/interfaces/cli/routes/index.js +2 -0
- package/src/interfaces/cli/routes/log.js +1 -1
- package/src/interfaces/cli/routes/memory.js +3 -2
- package/src/interfaces/cli/routes/panel.js +15 -2
- package/src/interfaces/cli/routes/profile.js +3 -2
- package/src/interfaces/cli/routes/transcribe.js +10 -0
- package/src/interfaces/cli/stdin.js +29 -0
- package/src/interfaces/desktop/assets/blobs/amatista.png +0 -0
- package/src/interfaces/desktop/assets/blobs/aqua.png +0 -0
- package/src/interfaces/desktop/assets/blobs/brasa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/campana.png +0 -0
- package/src/interfaces/desktop/assets/blobs/caracol.png +0 -0
- package/src/interfaces/desktop/assets/blobs/carbon.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cobalto.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cometa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/coral.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cubi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/eclipse.png +0 -0
- package/src/interfaces/desktop/assets/blobs/faro.png +0 -0
- package/src/interfaces/desktop/assets/blobs/gajo.png +0 -0
- package/src/interfaces/desktop/assets/blobs/iris.png +0 -0
- package/src/interfaces/desktop/assets/blobs/kiwi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/laguna.png +0 -0
- package/src/interfaces/desktop/assets/blobs/lila.png +0 -0
- package/src/interfaces/desktop/assets/blobs/menta.png +0 -0
- package/src/interfaces/desktop/assets/blobs/nimbo.png +0 -0
- package/src/interfaces/desktop/assets/blobs/noche.png +0 -0
- package/src/interfaces/desktop/assets/blobs/onyx.png +0 -0
- package/src/interfaces/desktop/assets/blobs/orbita.png +0 -0
- package/src/interfaces/desktop/assets/blobs/ovni.png +0 -0
- package/src/interfaces/desktop/assets/blobs/papa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/parche.png +0 -0
- package/src/interfaces/desktop/assets/blobs/peon.png +0 -0
- package/src/interfaces/desktop/assets/blobs/perla.png +0 -0
- package/src/interfaces/desktop/assets/blobs/pino.png +0 -0
- package/src/interfaces/desktop/assets/blobs/quad.png +0 -0
- package/src/interfaces/desktop/assets/blobs/rubi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/saturno.png +0 -0
- package/src/interfaces/desktop/assets/blobs/trebol.png +0 -0
- package/src/interfaces/desktop/assets/blobs/trino.png +0 -0
- package/src/interfaces/desktop/assets/blobs/volcan.png +0 -0
- package/src/interfaces/desktop/assets/blobs/zafiro.png +0 -0
- package/src/interfaces/desktop/assets/notification.mp3 +0 -0
- package/src/interfaces/desktop/main.js +473 -29
- package/src/interfaces/desktop/mascot-blobs.js +41 -0
- package/src/interfaces/desktop/mascot-preload.js +32 -0
- package/src/interfaces/desktop/mascot.css +186 -0
- package/src/interfaces/desktop/mascot.html +40 -0
- package/src/interfaces/desktop/mascot.js +163 -0
- package/src/interfaces/desktop/preload.js +10 -0
- package/src/interfaces/desktop/renderer.js +308 -48
- package/src/interfaces/desktop/style.css +34 -0
- package/src/interfaces/mcp-server/index.js +87 -0
- package/src/interfaces/tui/_shims/util-locale.ts +0 -2
- package/src/interfaces/tui/app.tsx +0 -6
- package/src/interfaces/tui/attach.ts +0 -1
- package/src/interfaces/tui/context/sdk-apx.tsx +0 -4
- package/src/interfaces/tui/plugin/api.tsx +0 -3
- package/src/interfaces/tui/plugin/runtime.ts +0 -3
- package/src/interfaces/tui/thread.ts +0 -16
- package/src/interfaces/web/README.md +22 -14
- package/src/interfaces/web/dist/assets/claude-XtpLmGtF.webp +0 -0
- package/src/interfaces/web/dist/assets/codex-DExPUgvh.webp +0 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css +32 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.br +0 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.gz +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js +1074 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.br +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.gz +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map +1 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.br +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.gz +0 -0
- package/src/interfaces/web/dist/favicon/dark/site.webmanifest +12 -6
- package/src/interfaces/web/dist/favicon/white/site.webmanifest +12 -6
- package/src/interfaces/web/dist/index.html +22 -6
- package/src/interfaces/web/dist/index.html.br +0 -0
- package/src/interfaces/web/dist/index.html.gz +0 -0
- package/src/interfaces/web/dist/manifest.webmanifest +25 -0
- package/src/interfaces/web/dist/modules/blobs/amatista.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/aqua.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/brasa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/campana.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/caracol.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/carbon.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cobalto.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cometa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/coral.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cubi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/eclipse.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/faro.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/gajo.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/iris.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/kiwi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/laguna.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/lila.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/menta.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/nimbo.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/noche.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/onyx.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/orbita.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/ovni.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/papa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/parche.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/peon.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/perla.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/pino.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/quad.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/rubi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/saturno.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/trebol.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/trino.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/volcan.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/zafiro.png +0 -0
- package/src/interfaces/web/dist/sw.js +106 -0
- package/src/interfaces/web/dist/sw.js.br +0 -0
- package/src/interfaces/web/dist/sw.js.gz +0 -0
- package/src/interfaces/web/eslint.config.js +83 -0
- package/src/interfaces/web/index.html +20 -4
- package/src/interfaces/web/package-lock.json +1651 -1280
- package/src/interfaces/web/package.json +9 -10
- package/src/interfaces/web/pnpm-lock.yaml +867 -869
- package/src/interfaces/web/public/favicon/dark/site.webmanifest +12 -6
- package/src/interfaces/web/public/favicon/white/site.webmanifest +12 -6
- package/src/interfaces/web/public/manifest.webmanifest +25 -0
- package/src/interfaces/web/public/modules/blobs/amatista.png +0 -0
- package/src/interfaces/web/public/modules/blobs/aqua.png +0 -0
- package/src/interfaces/web/public/modules/blobs/brasa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/campana.png +0 -0
- package/src/interfaces/web/public/modules/blobs/caracol.png +0 -0
- package/src/interfaces/web/public/modules/blobs/carbon.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cobalto.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cometa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/coral.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cubi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/eclipse.png +0 -0
- package/src/interfaces/web/public/modules/blobs/faro.png +0 -0
- package/src/interfaces/web/public/modules/blobs/gajo.png +0 -0
- package/src/interfaces/web/public/modules/blobs/iris.png +0 -0
- package/src/interfaces/web/public/modules/blobs/kiwi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/laguna.png +0 -0
- package/src/interfaces/web/public/modules/blobs/lila.png +0 -0
- package/src/interfaces/web/public/modules/blobs/menta.png +0 -0
- package/src/interfaces/web/public/modules/blobs/nimbo.png +0 -0
- package/src/interfaces/web/public/modules/blobs/noche.png +0 -0
- package/src/interfaces/web/public/modules/blobs/onyx.png +0 -0
- package/src/interfaces/web/public/modules/blobs/orbita.png +0 -0
- package/src/interfaces/web/public/modules/blobs/ovni.png +0 -0
- package/src/interfaces/web/public/modules/blobs/papa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/parche.png +0 -0
- package/src/interfaces/web/public/modules/blobs/peon.png +0 -0
- package/src/interfaces/web/public/modules/blobs/perla.png +0 -0
- package/src/interfaces/web/public/modules/blobs/pino.png +0 -0
- package/src/interfaces/web/public/modules/blobs/quad.png +0 -0
- package/src/interfaces/web/public/modules/blobs/rubi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/saturno.png +0 -0
- package/src/interfaces/web/public/modules/blobs/trebol.png +0 -0
- package/src/interfaces/web/public/modules/blobs/trino.png +0 -0
- package/src/interfaces/web/public/modules/blobs/volcan.png +0 -0
- package/src/interfaces/web/public/modules/blobs/zafiro.png +0 -0
- package/src/interfaces/web/public/sw.js +106 -0
- package/src/interfaces/web/src/App.tsx +106 -10
- package/src/interfaces/web/src/assets/cli/claude.webp +0 -0
- package/src/interfaces/web/src/assets/cli/codex.webp +0 -0
- package/src/interfaces/web/src/assets/cli/cursor.svg +1 -0
- package/src/interfaces/web/src/assets/cli/opencode.png +0 -0
- package/src/interfaces/web/src/components/Combobox.tsx +201 -0
- package/src/interfaces/web/src/components/MobileHint.tsx +95 -0
- package/src/interfaces/web/src/components/MobileLinkDialog.tsx +156 -0
- package/src/interfaces/web/src/components/ModelCombobox.tsx +21 -113
- package/src/interfaces/web/src/components/{routines/ReadOnlyBlock.tsx → ReadOnlyBlock.tsx} +13 -4
- package/src/interfaces/web/src/components/Roby.tsx +5 -3
- package/src/interfaces/web/src/components/RobyBubble.tsx +23 -5
- package/src/interfaces/web/src/components/RowMenu.tsx +46 -0
- package/src/interfaces/web/src/components/TimezoneSelect.tsx +4 -1
- package/src/interfaces/web/src/components/Toast.tsx +50 -14
- package/src/interfaces/web/src/components/UiSelect.tsx +12 -5
- package/src/interfaces/web/src/components/agents/AgentAvatar.tsx +171 -0
- package/src/interfaces/web/src/components/agents/AgentFormFields.tsx +42 -11
- package/src/interfaces/web/src/components/agents/AgentModelBadge.tsx +157 -0
- package/src/interfaces/web/src/components/agents/AgentModelSelect.tsx +57 -0
- package/src/interfaces/web/src/components/agents/AgentSkillsPicker.tsx +115 -0
- package/src/interfaces/web/src/components/agents/BlobAvatar.tsx +50 -0
- package/src/interfaces/web/src/components/agents/blobPresets.ts +50 -0
- package/src/interfaces/web/src/components/agents/modelCatalog.ts +66 -0
- package/src/interfaces/web/src/components/chat/ActionGroup.tsx +162 -0
- package/src/interfaces/web/src/components/chat/AskAnswersCard.tsx +4 -3
- package/src/interfaces/web/src/components/chat/AskQuestionsCard.tsx +1 -1
- package/src/interfaces/web/src/components/chat/Attachment.tsx +220 -0
- package/src/interfaces/web/src/components/chat/ChatList.tsx +226 -51
- package/src/interfaces/web/src/components/chat/ChatRowActivity.tsx +45 -0
- package/src/interfaces/web/src/components/chat/Composer.tsx +672 -23
- package/src/interfaces/web/src/components/chat/ComposerCommands.tsx +175 -0
- package/src/interfaces/web/src/components/chat/ComposerSuggest.tsx +215 -0
- package/src/interfaces/web/src/components/chat/ContextBar.tsx +133 -65
- package/src/interfaces/web/src/components/chat/InlineAskPanel.tsx +107 -47
- package/src/interfaces/web/src/components/chat/MessageBubble.tsx +460 -119
- package/src/interfaces/web/src/components/chat/MessageList.tsx +165 -18
- package/src/interfaces/web/src/components/chat/ReasoningBlock.tsx +58 -0
- package/src/interfaces/web/src/components/chat/SessionPicker.tsx +182 -0
- package/src/interfaces/web/src/components/chat/SkillTrace.tsx +183 -0
- package/src/interfaces/web/src/components/chat/ToolCall.tsx +11 -11
- package/src/interfaces/web/src/components/code/CodeContextTab.tsx +87 -53
- package/src/interfaces/web/src/components/code/CodeFileTree.tsx +11 -52
- package/src/interfaces/web/src/components/code/CodeFileViewer.tsx +5 -4
- package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +31 -7
- package/src/interfaces/web/src/components/code/CodeSessionList.tsx +32 -11
- package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +33 -3
- package/src/interfaces/web/src/components/code/CodeTerminal.tsx +5 -4
- package/src/interfaces/web/src/components/code/NewCodeSessionDialog.tsx +164 -0
- package/src/interfaces/web/src/components/commitments/CommitmentDetail.tsx +162 -0
- package/src/interfaces/web/src/components/commitments/CommitmentFormDialog.tsx +158 -0
- package/src/interfaces/web/src/components/commitments/CommitmentList.tsx +194 -0
- package/src/interfaces/web/src/components/commitments/commitmentState.tsx +46 -0
- package/src/interfaces/web/src/components/common/BulkActionBar.tsx +60 -0
- package/src/interfaces/web/src/components/common/ConfirmDialog.tsx +4 -1
- package/src/interfaces/web/src/components/common/SelectCheckbox.tsx +40 -0
- package/src/interfaces/web/src/components/common/TabNav.tsx +1 -1
- package/src/interfaces/web/src/components/cron/CronPicker.tsx +1 -1
- package/src/interfaces/web/src/components/files/FileBrowser.tsx +1 -1
- package/src/interfaces/web/src/components/files/FileTree.tsx +6 -4
- package/src/interfaces/web/src/components/files/FileViewer.tsx +9 -5
- package/src/interfaces/web/src/components/files/MarkdownPreview.tsx +45 -9
- package/src/interfaces/web/src/components/images/ImageDefaultsCard.tsx +93 -0
- package/src/interfaces/web/src/components/images/ImageProviderList.tsx +142 -0
- package/src/interfaces/web/src/components/images/ImageProviderModal.tsx +263 -0
- package/src/interfaces/web/src/components/images/ImageTestCard.tsx +142 -0
- package/src/interfaces/web/src/components/inbox/ChannelFilter.tsx +178 -0
- package/src/interfaces/web/src/components/inbox/InboxList.tsx +77 -81
- package/src/interfaces/web/src/components/inbox/InboxRowItem.tsx +140 -0
- package/src/interfaces/web/src/components/integrations/ComingSoonPlugin.tsx +2 -2
- package/src/interfaces/web/src/components/integrations/PluginConnect.tsx +208 -30
- package/src/interfaces/web/src/components/integrations/PluginToolsSection.tsx +1 -1
- package/src/interfaces/web/src/components/layout/ProjectAvatar.tsx +39 -24
- package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +253 -58
- package/src/interfaces/web/src/components/memory/MemoryBrowser.tsx +94 -47
- package/src/interfaces/web/src/components/routines/ExecutionsList.tsx +202 -90
- package/src/interfaces/web/src/components/routines/RoutineDetail.tsx +28 -6
- package/src/interfaces/web/src/components/routines/RoutineEditor.tsx +16 -5
- package/src/interfaces/web/src/components/routines/RoutineList.tsx +49 -9
- package/src/interfaces/web/src/components/routines/VarTextarea.tsx +1 -1
- package/src/interfaces/web/src/components/routines/runChat.ts +121 -0
- package/src/interfaces/web/src/components/sessions/SessionDetail.tsx +148 -0
- package/src/interfaces/web/src/components/sessions/SessionTerminal.tsx +98 -0
- package/src/interfaces/web/src/components/settings/AccessPanel.tsx +205 -0
- package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +246 -101
- package/src/interfaces/web/src/components/settings/DesktopSettingsPanel.tsx +36 -2
- package/src/interfaces/web/src/components/settings/DevicesPanel.tsx +19 -6
- package/src/interfaces/web/src/components/settings/EmbedProviderList.tsx +274 -0
- package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +26 -6
- package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +118 -119
- package/src/interfaces/web/src/components/settings/NudgePanel.tsx +4 -3
- package/src/interfaces/web/src/components/settings/PairDeviceDialog.tsx +15 -4
- package/src/interfaces/web/src/components/settings/PanelPrefs.tsx +374 -0
- package/src/interfaces/web/src/components/settings/ProfilePanel.tsx +70 -2
- package/src/interfaces/web/src/components/settings/RoutingPanel.tsx +2 -1
- package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +102 -43
- package/src/interfaces/web/src/components/settings/SkillsManager.tsx +76 -21
- package/src/interfaces/web/src/components/settings/SkillsSettings.tsx +10 -3
- package/src/interfaces/web/src/components/settings/SuperAgentPanel.tsx +8 -0
- package/src/interfaces/web/src/components/settings/TelegramChannelsPanel.tsx +11 -2
- package/src/interfaces/web/src/components/settings/TelegramContactsPanel.tsx +19 -8
- package/src/interfaces/web/src/components/settings/TelegramRolesPanel.tsx +12 -2
- package/src/interfaces/web/src/components/settings/WebPanel.tsx +22 -31
- package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +15 -3
- package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +97 -66
- package/src/interfaces/web/src/components/settings/providers/ProviderTestDialog.tsx +150 -0
- package/src/interfaces/web/src/components/settings/providers/typeStyles.ts +67 -25
- package/src/interfaces/web/src/components/settings/providers/types.ts +3 -0
- package/src/interfaces/web/src/components/tasks/TaskBoard.tsx +201 -0
- package/src/interfaces/web/src/components/tasks/TaskColumnsDialog.tsx +243 -0
- package/src/interfaces/web/src/components/tasks/TaskComments.tsx +167 -0
- package/src/interfaces/web/src/components/tasks/TaskDetail.tsx +335 -0
- package/src/interfaces/web/src/components/tasks/TaskFormDialog.tsx +406 -0
- package/src/interfaces/web/src/components/tasks/TaskList.tsx +258 -0
- package/src/interfaces/web/src/components/tasks/TaskSubtasks.tsx +126 -0
- package/src/interfaces/web/src/components/tasks/columns.ts +51 -0
- package/src/interfaces/web/src/components/tasks/taskStatus.tsx +159 -34
- package/src/interfaces/web/src/components/tasks/taskViewPrefs.ts +73 -0
- package/src/interfaces/web/src/components/tasks/useTaskColumns.ts +31 -0
- package/src/interfaces/web/src/components/ui/chat-input.tsx +136 -12
- package/src/interfaces/web/src/components/ui/context-menu.tsx +15 -198
- package/src/interfaces/web/src/components/ui/dialog.tsx +3 -2
- package/src/interfaces/web/src/components/ui/filter-chips.tsx +4 -0
- package/src/interfaces/web/src/components/ui/popover.tsx +14 -49
- package/src/interfaces/web/src/components/ui/sheet.tsx +2 -1
- package/src/interfaces/web/src/components/ui/spinner.tsx +2 -1
- package/src/interfaces/web/src/components/ui.tsx +62 -23
- package/src/interfaces/web/src/components/voice/VoiceProviderList.tsx +2 -1
- package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +66 -8
- package/src/interfaces/web/src/components/voice/VoiceQvoxInstallCard.tsx +63 -0
- package/src/interfaces/web/src/components/voice/VoiceQvoxStatusCard.tsx +51 -0
- package/src/interfaces/web/src/components/voice/VoiceSttCard.tsx +4 -3
- package/src/interfaces/web/src/components/voice/VoiceTestCard.tsx +38 -4
- package/src/interfaces/web/src/constants/index.ts +1 -0
- package/src/interfaces/web/src/hooks/useChannelPrefs.ts +39 -0
- package/src/interfaces/web/src/hooks/useChat.ts +1092 -85
- package/src/interfaces/web/src/hooks/useChatActivity.ts +24 -0
- package/src/interfaces/web/src/hooks/useInbox.ts +26 -4
- package/src/interfaces/web/src/hooks/useLiveMessages.ts +16 -0
- package/src/interfaces/web/src/hooks/useOllamaModels.ts +79 -0
- package/src/interfaces/web/src/hooks/useRecorder.ts +198 -0
- package/src/interfaces/web/src/hooks/useTokenBootstrap.ts +23 -6
- package/src/interfaces/web/src/i18n/en.ts +832 -175
- package/src/interfaces/web/src/i18n/es.ts +841 -188
- package/src/interfaces/web/src/lib/api/agents.ts +23 -4
- package/src/interfaces/web/src/lib/api/code.ts +17 -0
- package/src/interfaces/web/src/lib/api/commitments.ts +7 -1
- package/src/interfaces/web/src/lib/api/conversations.ts +38 -11
- package/src/interfaces/web/src/lib/api/embeddings.ts +3 -0
- package/src/interfaces/web/src/lib/api/engines.ts +14 -0
- package/src/interfaces/web/src/lib/api/groups.ts +93 -0
- package/src/interfaces/web/src/lib/api/images.ts +193 -0
- package/src/interfaces/web/src/lib/api/inbox.ts +29 -5
- package/src/interfaces/web/src/lib/api/integrations.ts +9 -0
- package/src/interfaces/web/src/lib/api/media.ts +126 -0
- package/src/interfaces/web/src/lib/api/net.ts +44 -0
- package/src/interfaces/web/src/lib/api/profiles.ts +12 -0
- package/src/interfaces/web/src/lib/api/projects.ts +9 -1
- package/src/interfaces/web/src/lib/api/routines.ts +9 -1
- package/src/interfaces/web/src/lib/api/sessions.ts +18 -0
- package/src/interfaces/web/src/lib/api/skills.ts +8 -0
- package/src/interfaces/web/src/lib/api/super_agent.ts +3 -0
- package/src/interfaces/web/src/lib/api/tasks.ts +46 -6
- package/src/interfaces/web/src/lib/api/tools.ts +2 -0
- package/src/interfaces/web/src/lib/api/transcribe.ts +31 -0
- package/src/interfaces/web/src/lib/api/turns.ts +20 -0
- package/src/interfaces/web/src/lib/api/voice.ts +72 -2
- package/src/interfaces/web/src/lib/api.ts +3 -0
- package/src/interfaces/web/src/lib/channels.ts +214 -0
- package/src/interfaces/web/src/lib/chat-activity.ts +175 -0
- package/src/interfaces/web/src/lib/chat-prefs.ts +48 -0
- package/src/interfaces/web/src/lib/code-context.ts +0 -2
- package/src/interfaces/web/src/lib/http.ts +51 -17
- package/src/interfaces/web/src/lib/inbox-selection.ts +29 -0
- package/src/interfaces/web/src/lib/live.ts +252 -0
- package/src/interfaces/web/src/lib/net.ts +211 -0
- package/src/interfaces/web/src/lib/notify.ts +331 -0
- package/src/interfaces/web/src/lib/projectNav.ts +40 -0
- package/src/interfaces/web/src/lib/pwa.ts +115 -0
- package/src/interfaces/web/src/lib/qvox.ts +24 -0
- package/src/interfaces/web/src/lib/slug.ts +3 -0
- package/src/interfaces/web/src/lib/tone.ts +150 -0
- package/src/interfaces/web/src/main.tsx +15 -4
- package/src/interfaces/web/src/screens/ApxAdminScreen.tsx +33 -11
- package/src/interfaces/web/src/screens/InboxScreen.tsx +126 -71
- package/src/interfaces/web/src/screens/ProjectScreen.tsx +8 -4
- package/src/interfaces/web/src/screens/SettingsScreen.tsx +7 -4
- package/src/interfaces/web/src/screens/base/AgentDefaultsTab.tsx +30 -9
- package/src/interfaces/web/src/screens/base/CommitmentsTab.tsx +150 -168
- package/src/interfaces/web/src/screens/base/LogsTab.tsx +8 -7
- package/src/interfaces/web/src/screens/base/SessionsTab.tsx +99 -37
- package/src/interfaces/web/src/screens/base/WorkspacesTab.tsx +1 -1
- package/src/interfaces/web/src/screens/mobile/MobileChat.tsx +85 -0
- package/src/interfaces/web/src/screens/mobile/MobileChatList.tsx +244 -0
- package/src/interfaces/web/src/screens/mobile/MobileCommitments.tsx +350 -0
- package/src/interfaces/web/src/screens/mobile/MobileScreen.tsx +138 -0
- package/src/interfaces/web/src/screens/mobile/MobileTabBar.tsx +105 -0
- package/src/interfaces/web/src/screens/mobile/MobileTasks.tsx +407 -0
- package/src/interfaces/web/src/screens/mobile/NewChatSheet.tsx +313 -0
- package/src/interfaces/web/src/screens/mobile/mobileList.tsx +194 -0
- package/src/interfaces/web/src/screens/mobile/routes.ts +239 -0
- package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +135 -64
- package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +0 -1
- package/src/interfaces/web/src/screens/modules/ImagesScreen.tsx +172 -0
- package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +36 -4
- package/src/interfaces/web/src/screens/project/AgentBrainGraph.tsx +117 -30
- package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +537 -92
- package/src/interfaces/web/src/screens/project/AgentsTab.tsx +344 -93
- package/src/interfaces/web/src/screens/project/ArtifactsTab.tsx +1 -1
- package/src/interfaces/web/src/screens/project/ChatTab.tsx +1160 -94
- package/src/interfaces/web/src/screens/project/IntegrationsTab.tsx +3 -2
- package/src/interfaces/web/src/screens/project/McpsTab.tsx +62 -14
- package/src/interfaces/web/src/screens/project/Overview.tsx +36 -15
- package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +93 -8
- package/src/interfaces/web/src/screens/project/SkillsTab.tsx +4 -1
- package/src/interfaces/web/src/screens/project/StructureTab.tsx +5 -4
- package/src/interfaces/web/src/screens/project/TasksTab.tsx +351 -129
- package/src/interfaces/web/src/screens/project/VarsTab.tsx +17 -5
- package/src/interfaces/web/src/styles.css +106 -31
- package/src/interfaces/web/src/types/daemon.ts +246 -2
- package/src/interfaces/web/src/vite-env.d.ts +20 -0
- package/src/interfaces/tui/plugin/command-shim.ts +0 -109
- package/src/interfaces/web/components.json +0 -25
- package/src/interfaces/web/dist/assets/index-CvEoGtTf.js +0 -849
- package/src/interfaces/web/dist/assets/index-CvEoGtTf.js.map +0 -1
- package/src/interfaces/web/dist/assets/index-DzBBXFaO.css +0 -1
- package/src/interfaces/web/src/components/tasks/TaskDetailPanel.tsx +0 -142
- package/src/interfaces/web/src/components/ui/accordion.tsx +0 -72
- package/src/interfaces/web/src/components/ui/alert-dialog.tsx +0 -187
- package/src/interfaces/web/src/components/ui/alert.tsx +0 -76
- package/src/interfaces/web/src/components/ui/aspect-ratio.tsx +0 -22
- package/src/interfaces/web/src/components/ui/avatar.tsx +0 -107
- package/src/interfaces/web/src/components/ui/breadcrumb.tsx +0 -125
- package/src/interfaces/web/src/components/ui/button-group.tsx +0 -87
- package/src/interfaces/web/src/components/ui/calendar.tsx +0 -221
- package/src/interfaces/web/src/components/ui/card.tsx +0 -103
- package/src/interfaces/web/src/components/ui/carousel.tsx +0 -242
- package/src/interfaces/web/src/components/ui/chart.tsx +0 -371
- package/src/interfaces/web/src/components/ui/checkbox.tsx +0 -29
- package/src/interfaces/web/src/components/ui/collapsible.tsx +0 -19
- package/src/interfaces/web/src/components/ui/combobox.tsx +0 -295
- package/src/interfaces/web/src/components/ui/command.tsx +0 -196
- package/src/interfaces/web/src/components/ui/direction.tsx +0 -4
- package/src/interfaces/web/src/components/ui/drawer.tsx +0 -134
- package/src/interfaces/web/src/components/ui/empty.tsx +0 -104
- package/src/interfaces/web/src/components/ui/field.tsx +0 -236
- package/src/interfaces/web/src/components/ui/hover-card.tsx +0 -51
- package/src/interfaces/web/src/components/ui/input-otp.tsx +0 -85
- package/src/interfaces/web/src/components/ui/item.tsx +0 -201
- package/src/interfaces/web/src/components/ui/menubar.tsx +0 -280
- package/src/interfaces/web/src/components/ui/native-select.tsx +0 -61
- package/src/interfaces/web/src/components/ui/navigation-menu.tsx +0 -168
- package/src/interfaces/web/src/components/ui/pagination.tsx +0 -130
- package/src/interfaces/web/src/components/ui/progress.tsx +0 -83
- package/src/interfaces/web/src/components/ui/radio-group.tsx +0 -36
- package/src/interfaces/web/src/components/ui/resizable.tsx +0 -50
- package/src/interfaces/web/src/components/ui/scroll-area.tsx +0 -53
- package/src/interfaces/web/src/components/ui/sidebar.tsx +0 -726
- package/src/interfaces/web/src/components/ui/slider.tsx +0 -52
- package/src/interfaces/web/src/components/ui/sonner.tsx +0 -49
- package/src/interfaces/web/src/components/ui/table.tsx +0 -116
- package/src/interfaces/web/src/components/ui/toggle-group.tsx +0 -87
- package/src/interfaces/web/src/components/ui/toggle.tsx +0 -45
- package/src/interfaces/web/src/hooks/use-mobile.ts +0 -19
- package/src/interfaces/web/src/screens/base/GlobalTasksTab.tsx +0 -161
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: apx-telegram
|
|
3
|
-
description: APX Telegram plugin — channels, project pinning, master agents, media. Load BEFORE configuring a new bot or routing —
|
|
3
|
+
description: APX Telegram plugin — channels, project pinning, master agents, media. Load BEFORE configuring a new bot or routing — channels[] is the only place credentials live.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# apx-telegram
|
|
@@ -21,7 +21,7 @@ APX polls `getUpdates` and routes messages. Config: `~/.apx/config.json → tele
|
|
|
21
21
|
"name": "default",
|
|
22
22
|
"bot_token": "<from BotFather>",
|
|
23
23
|
"chat_id": "<numeric chat id>",
|
|
24
|
-
"project": "
|
|
24
|
+
"project": "acme", // optional: pin to project
|
|
25
25
|
"route_to_agent": "reviewer", // optional: per-channel agent
|
|
26
26
|
"respond_with_engine": true, // optional: override global
|
|
27
27
|
"owner_user_id": "123456789" // optional: via `apx telegram owner`
|
|
@@ -33,19 +33,19 @@ APX polls `getUpdates` and routes messages. Config: `~/.apx/config.json → tele
|
|
|
33
33
|
}
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
Root `telegram.bot_token` / `telegram.chat_id` are **
|
|
36
|
+
Root `telegram.bot_token` / `telegram.chat_id` are **not read**. APX drops them on load, so a token written there silently does nothing — always use `channels[]`. With `channels[]` empty, APX polls one implicit `default` channel using `BOT_TELEGRAM_TOKEN` / `TELEGRAM_CHAT_ID` from the environment.
|
|
37
37
|
|
|
38
38
|
## Concrete CLI calls
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
apx telegram setup #
|
|
41
|
+
apx telegram setup # prints the config template (channels[] shape)
|
|
42
42
|
|
|
43
43
|
# Channels CRUD
|
|
44
44
|
apx telegram channel add # interactive
|
|
45
|
-
apx telegram channel add clientes --bot-token <T> --chat-id <C> --project
|
|
45
|
+
apx telegram channel add clientes --bot-token <T> --chat-id <C> --project acme --agent reviewer
|
|
46
46
|
apx telegram channel list # alias: ls
|
|
47
47
|
apx telegram channel show clientes # alias: get
|
|
48
|
-
apx telegram channel set clientes --project
|
|
48
|
+
apx telegram channel set clientes --project acme
|
|
49
49
|
apx telegram channel set clientes --agent reviewer
|
|
50
50
|
apx telegram channel set clientes --respond-engine false
|
|
51
51
|
apx telegram channel unset clientes --project --agent
|
|
@@ -85,20 +85,20 @@ Every `channel` CRUD write triggers `POST /api/admin/reload` so polling picks up
|
|
|
85
85
|
|
|
86
86
|
## What "pin to project" does
|
|
87
87
|
|
|
88
|
-
On a message to a channel with `project: "
|
|
89
|
-
1. The super-agent invocation gets `channelMeta.projectId = <
|
|
88
|
+
On a message to a channel with `project: "acme"`:
|
|
89
|
+
1. The super-agent invocation gets `channelMeta.projectId = <acme's id>`.
|
|
90
90
|
2. The system prompt resolves project-scoped agents, MCPs, memory.
|
|
91
|
-
3. Tools (`list_agents`, `list_tasks`, `create_task`, …) default to that project — no need to repeat "in
|
|
91
|
+
3. Tools (`list_agents`, `list_tasks`, `create_task`, …) default to that project — no need to repeat "in acme" each message.
|
|
92
92
|
|
|
93
93
|
## What "master agent" does
|
|
94
94
|
|
|
95
|
-
With `route_to_agent: "reviewer"`,
|
|
95
|
+
With `route_to_agent: "reviewer"`, an incoming message is dispatched to that project agent instead of the super-agent. Routing is **in-process** — `src/core/channels/telegram/dispatch.js` reads the agent and makes a single `callEngine` with the agent's `AGENT.md` + memory (there is no per-request `agents/:slug/chat` HTTP route). No tools: text in, text out. Use this for persona channels (reviewer, sales, support) instead of the general assistant. Empty = super-agent (default).
|
|
96
96
|
|
|
97
97
|
## Anti-examples
|
|
98
98
|
|
|
99
99
|
```bash
|
|
100
|
-
# DON'T write to
|
|
101
|
-
apx config set telegram.bot_token "<T>" # ← use channels[] via `apx telegram channel`
|
|
100
|
+
# DON'T write to the root fields — they are dropped on load.
|
|
101
|
+
apx config set --global telegram.bot_token "<T>" # ← use channels[] via `apx telegram channel`
|
|
102
102
|
|
|
103
103
|
# DON'T expect routing magic from same project on two channels.
|
|
104
104
|
# A channel pins messages TO a project, not vice-versa. Same project from multiple
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: apx-transcribe
|
|
3
|
+
scope: optional
|
|
4
|
+
description: Transcribe audio and video files to text from the command line with `apx transcribe`, using the daemon's built-in Whisper. Load when asked to transcribe a voice note, an audio clip, or a video's speech, to batch-transcribe a folder, to pipe transcription into a script, or when choosing between the local, cloud, or a networked custom STT engine.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# apx-transcribe
|
|
8
|
+
|
|
9
|
+
`apx transcribe` is a thin CLI over the daemon's speech-to-text engine — the same persistent `whisper-server.py` that powers the desktop overlay and Telegram voice notes (`core/voice/transcription.js`). The model is preloaded at daemon boot, so calls hit a warm server and stay fast. This is the fastest way to turn a file on disk into text without writing any HTTP.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
apx transcribe nota.oga # transcript to stdout, nothing else
|
|
15
|
+
apx transcribe reunion.mp4 # video: the audio track is extracted
|
|
16
|
+
apx transcribe a.wav b.m4a c.mp3 # bulk: one "── name ──" block per file
|
|
17
|
+
apx transcribe ./notas-de-voz/ # every audio/video file in a folder
|
|
18
|
+
apx transcribe voz.webm --lang es # pin the language (else auto-detect)
|
|
19
|
+
apx transcribe *.mp3 --json > out.json # machine-readable array
|
|
20
|
+
cat clip.wav | apx transcribe - # read audio from stdin
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Formats
|
|
24
|
+
|
|
25
|
+
Audio: `webm`, `ogg`/`oga`, `opus`, `m4a`, `aac`, `mp3`, `wav`, `flac`. Video: `mp4`, `mov`, `mkv`, `m4v`, `avi`, `3gp` and more. The daemon shells out to `ffmpeg`, which probes the real container from the bytes and pulls the audio track out of a video — so the extension is only a hint, and a mislabelled file still works.
|
|
26
|
+
|
|
27
|
+
## Provider routing (`--provider`)
|
|
28
|
+
|
|
29
|
+
The `--provider` flag overrides the configured STT routing for one call:
|
|
30
|
+
|
|
31
|
+
| id | What it is |
|
|
32
|
+
|---|---|
|
|
33
|
+
| `local` | The embedded Whisper. On Apple Silicon it runs on `mlx` (Metal GPU), on NVIDIA on `faster-whisper` cuda, else CPU — picked automatically. |
|
|
34
|
+
| `openai` | Cloud Whisper (`whisper-1`). Needs `OPENAI_API_KEY` or `engines.openai.api_key`. |
|
|
35
|
+
| `custom` | Any OpenAI-compatible STT server reachable over the network — mlx-audio on this Mac, a Radeon/NVIDIA box on the LAN, or a remote endpoint. Configured under `transcription.custom.base_url`. |
|
|
36
|
+
|
|
37
|
+
Default routing lives in `~/.apx/config.json` under `transcription.provider` (`auto` tries local first, falls back to OpenAI if a key is set).
|
|
38
|
+
|
|
39
|
+
## Output contract (why it is scriptable)
|
|
40
|
+
|
|
41
|
+
- **One file** → the bare transcript on **stdout**, one trailing newline. Pipe-friendly: `apx transcribe x.oga | pbcopy` copies clean text.
|
|
42
|
+
- **Many files / a folder** → a `── filename ──` header before each transcript.
|
|
43
|
+
- **`--json`** → the full result object (`text`, `language`, `backend`, `model`, …) for one file, or an array of `{file, ...}` in bulk.
|
|
44
|
+
- The `▸ APX CLI` banner always goes to **stderr**, never stdout.
|
|
45
|
+
- Bulk runs **sequentially** (the local model is single-instance) and keeps going past a failed file, exiting non-zero if any failed.
|
|
46
|
+
|
|
47
|
+
## How it works
|
|
48
|
+
|
|
49
|
+
The CLI reads the file bytes and POSTs them to the daemon's `POST /api/transcribe/chunk` with `X-Audio-Format`, `X-Language`, and optional `X-Provider` headers. That endpoint is the shared "any external caller" entry point, so a routine's `pre_command`, a hook, or a plain shell script all get the same warm engine without spawning their own Whisper. Long media is allowed up to 20 minutes per request.
|
|
50
|
+
|
|
51
|
+
## Don't
|
|
52
|
+
|
|
53
|
+
- Don't spin up a separate Whisper process or a Python script to transcribe — the daemon already runs a warm one; `apx transcribe` reuses it. A parallel instance just fights for the GPU.
|
|
54
|
+
- Don't restart the daemon to "load" the model before transcribing — it is preloaded at boot, and the endpoint lazily re-spawns it after the idle-shutdown anyway.
|
|
55
|
+
- Don't pre-extract audio from a video before transcribing it — pass the video directly; the daemon's ffmpeg handles the audio track.
|
|
56
|
+
- Don't parse the human transcript when you need fields — use `--json` and read `text`, never scrape stdout for the language or model.
|
|
@@ -35,9 +35,9 @@ When `base_url` is set, APX additionally forwards the non-OpenAI fields the serv
|
|
|
35
35
|
Some backends (QVox/Qwen3-TTS, Gemini) accept inline `[tag]` markers and switch speaking emotion per segment while keeping the base voice. This is a **generic per-engine toggle**, not hardcoded to any adapter:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
apx config set voice.tts.custom.qvox.emotions.enabled true
|
|
38
|
+
apx config set --global voice.tts.custom.qvox.emotions.enabled true
|
|
39
39
|
# optional: restrict the tag set (defaults to the canonical QVox set)
|
|
40
|
-
apx config set voice.tts.custom.qvox.emotions.tags '["happy","sad","excited","calm","whisper","laugh","neutral"]'
|
|
40
|
+
apx config set --global voice.tts.custom.qvox.emotions.tags '["happy","sad","excited","calm","whisper","laugh","neutral"]'
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
Default tags: `happy, sad, excited, angry, calm, whisper, shout, laugh, cry, narrator, neutral`. The voice-mode prompt learns the tag syntax **only when the engine that will actually speak has emotions enabled**. On any engine without tag support, stray `[tags]` are stripped from the displayed text and never read aloud (kept only for the speaking engine's audio).
|
|
@@ -57,6 +57,23 @@ apx voice listen --provider <id> # override STT provider
|
|
|
57
57
|
|
|
58
58
|
Playback uses system binaries (`afplay`, `paplay`, `aplay`, `play`, `ffplay`). If none found, you get the file path and no playback.
|
|
59
59
|
|
|
60
|
+
## Spoken replies while driving
|
|
61
|
+
|
|
62
|
+
When the daemon knows a trip is in progress (Android reports it — see
|
|
63
|
+
`rules/android.md`), every automatic Telegram reply goes out twice: a voice note
|
|
64
|
+
first, then the same words as text under a transcript header. The turn itself
|
|
65
|
+
runs in voice mode, so the reply is one or two spoken sentences rather than a
|
|
66
|
+
paragraph read aloud.
|
|
67
|
+
|
|
68
|
+
The audio is OGG/Opus — the only container Telegram renders as a voice note —
|
|
69
|
+
converted from whatever the engine returned via `ffmpeg`. A failing engine or a
|
|
70
|
+
missing `ffmpeg` costs the audio, never the message: it falls back to plain
|
|
71
|
+
text. The `mock` engine is silence, not speech, and is refused.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
apx config set --global voice.mobility_replies false # keep replies text-only in the car
|
|
75
|
+
```
|
|
76
|
+
|
|
60
77
|
## Configuration
|
|
61
78
|
|
|
62
79
|
`~/.apx/config.json → voice.tts.<engine>`:
|
|
@@ -85,7 +102,7 @@ Playback uses system binaries (`afplay`, `paplay`, `aplay`, `play`, `ffplay`). I
|
|
|
85
102
|
}
|
|
86
103
|
```
|
|
87
104
|
|
|
88
|
-
`apx config set voice.tts.provider <name>` to switch.
|
|
105
|
+
`apx config set --global voice.tts.provider <name>` to switch. Voice config is read from the global config, so `--global` is required — without it the value lands in a project's `.apc/config.json` and the voice stack never sees it.
|
|
89
106
|
|
|
90
107
|
## Quick setup: Piper local (recommended, no internet)
|
|
91
108
|
|
|
@@ -101,17 +118,17 @@ curl -LO https://huggingface.co/rhasspy/piper-voices/resolve/main/es/es_AR/danie
|
|
|
101
118
|
curl -LO https://huggingface.co/rhasspy/piper-voices/resolve/main/es/es_AR/daniela/high/es_AR-daniela-high.onnx.json
|
|
102
119
|
|
|
103
120
|
# 3. Configure + test
|
|
104
|
-
apx config set voice.tts.provider piper
|
|
105
|
-
apx config set voice.tts.piper.model "$HOME/.apx/voices/es_AR-daniela-high.onnx"
|
|
121
|
+
apx config set --global voice.tts.provider piper
|
|
122
|
+
apx config set --global voice.tts.piper.model "$HOME/.apx/voices/es_AR-daniela-high.onnx"
|
|
106
123
|
apx voice say "hola, soy APX" --provider piper
|
|
107
124
|
```
|
|
108
125
|
|
|
109
126
|
## Quick setup: Gemini cloud
|
|
110
127
|
|
|
111
128
|
```bash
|
|
112
|
-
apx config set voice.tts.provider gemini
|
|
113
|
-
apx config set voice.tts.gemini.api_key '<GEMINI_KEY>'
|
|
114
|
-
apx config set engines.gemini.api_key '<GEMINI_KEY>' # reuse for LLM router
|
|
129
|
+
apx config set --global voice.tts.provider gemini
|
|
130
|
+
apx config set --global voice.tts.gemini.api_key '<GEMINI_KEY>'
|
|
131
|
+
apx config set --global engines.gemini.api_key '<GEMINI_KEY>' # reuse for LLM router
|
|
115
132
|
apx voice say "Hello from APX" --provider gemini
|
|
116
133
|
```
|
|
117
134
|
|
|
@@ -126,6 +143,8 @@ curl -X POST http://127.0.0.1:7430/api/voice/turn \
|
|
|
126
143
|
-d '{"text":"Hello APX","channel":"voice"}'
|
|
127
144
|
```
|
|
128
145
|
|
|
146
|
+
`channel` names the surface the turn arrives on: `voice` (the deck's spoken mode), `deck`, `desktop`, `telegram`. Anything else — including omitting it — is treated as `api`, the bounded default: the route will not adopt another surface's behaviour just because a caller names it.
|
|
147
|
+
|
|
129
148
|
Telegram voice messages and overlay mascot still have their own STT pipelines — they don't go through `/api/voice/turn` yet.
|
|
130
149
|
|
|
131
150
|
## Anti-examples
|
|
@@ -71,6 +71,14 @@ claude --continue # most recent session
|
|
|
71
71
|
claude -p --resume <session-id> "..." # specific session, always with -p (print mode)
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
## Not here: agent-to-agent (a2a) hand-off
|
|
75
|
+
|
|
76
|
+
Reaching an APX agent and being answered back (the a2a relay: `apx send … --deliver`,
|
|
77
|
+
`engine=… session=…` identity, `apx session resume … --msg`) is a **harness-side**
|
|
78
|
+
concern. It lives in the `apx` skill that every coding CLI loads, and on the agent
|
|
79
|
+
side in **apx-runtime**. This driver covers only how APX operates the Claude
|
|
80
|
+
engine — keep a2a out of it.
|
|
81
|
+
|
|
74
82
|
## APX runtime
|
|
75
83
|
|
|
76
84
|
Run a project agent through Claude Code:
|
|
@@ -40,8 +40,14 @@ apx config --help
|
|
|
40
40
|
apx status
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
Then update only non-secret project-safe settings. Keep API keys in
|
|
44
|
-
in `.apc/` or git
|
|
43
|
+
Then update only non-secret project-safe settings. Keep API keys in the global config or the
|
|
44
|
+
environment, never in `.apc/` or git — `apx config set` writes the project's committed
|
|
45
|
+
`.apc/config.json` unless you pass `--global`:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
apx config set --global engines.openrouter.api_key '<KEY>' # ~/.apx/config.json
|
|
49
|
+
apx config set engines.openrouter.model <model-id> # .apc/config.json (committed)
|
|
50
|
+
```
|
|
45
51
|
|
|
46
52
|
## OpenCode guidance
|
|
47
53
|
|
|
@@ -6,9 +6,17 @@ const DEFAULT_TIMEOUT = 5 * 60 * 1000; // 5 minutes
|
|
|
6
6
|
|
|
7
7
|
export function runProcess({ command, args = [], stdin = "", cwd, env, timeoutMs = DEFAULT_TIMEOUT }) {
|
|
8
8
|
return new Promise((resolve) => {
|
|
9
|
+
// `cwd` moves the child's working directory but NOT its inherited `PWD`,
|
|
10
|
+
// which still names wherever the daemon was started. Tools that trust `PWD`
|
|
11
|
+
// over getcwd() — opencode does — then resolve the wrong project: an a2a
|
|
12
|
+
// coding session asked to write a file wrote it into the daemon's checkout
|
|
13
|
+
// instead of the caller's. Keep the two in agreement.
|
|
14
|
+
const childEnv = { ...process.env, ...(env || {}) };
|
|
15
|
+
if (cwd) childEnv.PWD = cwd;
|
|
16
|
+
|
|
9
17
|
const child = spawn(command, args, {
|
|
10
18
|
cwd,
|
|
11
|
-
env:
|
|
19
|
+
env: childEnv,
|
|
12
20
|
stdio: ["pipe", "pipe", "pipe"],
|
|
13
21
|
});
|
|
14
22
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Claude Code runtime adapter. Uses the headless `-p` mode:
|
|
2
2
|
// claude -p "<prompt>" --append-system-prompt "<system>" --output-format json
|
|
3
|
+
// claude -p "<prompt>" --resume <session-id> continue that session
|
|
3
4
|
// Returns one JSON line with the result and session_id.
|
|
4
5
|
// Reference: https://docs.claude.com/en/docs/claude-code/headless
|
|
5
6
|
|
|
@@ -33,8 +34,15 @@ export default {
|
|
|
33
34
|
binary: "claude",
|
|
34
35
|
versionFlag: "--version",
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
sessions: "capture",
|
|
38
|
+
|
|
39
|
+
async run({ system, prompt, cwd, env, timeoutMs, resumeSessionId = null, mode = "code" }) {
|
|
37
40
|
const args = ["-p", prompt, "--output-format", "json"];
|
|
41
|
+
// `plan` is Claude Code's own read-only mode: it answers normally but will
|
|
42
|
+
// not edit. That is what a plain a2a message should get — a peer you talked
|
|
43
|
+
// to should not be able to rewrite your checkout because it was asked to.
|
|
44
|
+
if (mode === "chat") args.push("--permission-mode", "plan");
|
|
45
|
+
if (resumeSessionId) args.push("--resume", resumeSessionId);
|
|
38
46
|
if (system) {
|
|
39
47
|
args.push("--append-system-prompt", system);
|
|
40
48
|
}
|
|
@@ -70,8 +78,9 @@ export default {
|
|
|
70
78
|
exitCode: r.exitCode,
|
|
71
79
|
output,
|
|
72
80
|
stderr: r.stderr,
|
|
81
|
+
killed: r.killed,
|
|
73
82
|
externalSessionPath,
|
|
74
|
-
sessionId,
|
|
83
|
+
sessionId: sessionId || resumeSessionId || null,
|
|
75
84
|
raw: parsed,
|
|
76
85
|
};
|
|
77
86
|
},
|
|
@@ -1,29 +1,63 @@
|
|
|
1
1
|
// OpenAI Codex CLI runtime adapter.
|
|
2
|
-
// codex exec --sandbox workspace-write --skip-git-repo-check "<prompt>"
|
|
2
|
+
// codex exec --sandbox workspace-write --skip-git-repo-check --json "<prompt>"
|
|
3
|
+
// codex exec resume <thread-id> --json "<prompt>" continue that thread
|
|
3
4
|
// System prompt is prepended to the prompt body since Codex doesn't have a
|
|
4
5
|
// dedicated --system flag in `exec` mode.
|
|
5
6
|
// Reference: https://github.com/openai/codex
|
|
6
7
|
|
|
7
8
|
import { runProcess } from "./_spawn.js";
|
|
8
9
|
|
|
10
|
+
// `--json` turns stdout into JSONL events. We ask for it because it is the only
|
|
11
|
+
// place codex names the thread it opened, and that id is what lets the NEXT
|
|
12
|
+
// turn resume this same conversation instead of starting a stranger. The prose
|
|
13
|
+
// we would otherwise have printed is in the agent_message items.
|
|
14
|
+
function parseCodexEvents(stdout) {
|
|
15
|
+
let threadId = null;
|
|
16
|
+
const messages = [];
|
|
17
|
+
for (const raw of String(stdout || "").split("\n")) {
|
|
18
|
+
const line = raw.trim();
|
|
19
|
+
if (!line.startsWith("{")) continue;
|
|
20
|
+
let event;
|
|
21
|
+
try { event = JSON.parse(line); } catch { continue; }
|
|
22
|
+
if (event.type === "thread.started" && event.thread_id) threadId = event.thread_id;
|
|
23
|
+
if (
|
|
24
|
+
event.type === "item.completed" &&
|
|
25
|
+
event.item?.type === "agent_message" &&
|
|
26
|
+
event.item.text
|
|
27
|
+
) {
|
|
28
|
+
messages.push(String(event.item.text));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { threadId, text: messages.join("\n\n").trim() };
|
|
32
|
+
}
|
|
33
|
+
|
|
9
34
|
export default {
|
|
10
35
|
id: "codex",
|
|
11
36
|
binary: "codex",
|
|
12
37
|
versionFlag: "--version",
|
|
38
|
+
sessions: "capture",
|
|
13
39
|
|
|
14
|
-
async run({ system, prompt, cwd, env, timeoutMs }) {
|
|
40
|
+
async run({ system, prompt, cwd, env, timeoutMs, resumeSessionId = null, mode = "code" }) {
|
|
15
41
|
const fullPrompt = system ? `${system}\n\n---\n\n${prompt}` : prompt;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
42
|
+
// `exec resume` takes no --sandbox: it inherits the sandbox the thread was
|
|
43
|
+
// opened with, and passing the flag is an error rather than a no-op. Which
|
|
44
|
+
// means the FIRST turn decides what the thread may touch for its whole life.
|
|
45
|
+
const sandbox = mode === "chat" ? "read-only" : "workspace-write";
|
|
46
|
+
const args = resumeSessionId
|
|
47
|
+
? ["exec", "resume", resumeSessionId, "--skip-git-repo-check", "--json", fullPrompt]
|
|
48
|
+
: ["exec", "--sandbox", sandbox, "--skip-git-repo-check", "--json", fullPrompt];
|
|
49
|
+
|
|
50
|
+
const r = await runProcess({ command: "codex", args, cwd, env, timeoutMs });
|
|
51
|
+
const { threadId, text } = parseCodexEvents(r.stdout);
|
|
52
|
+
|
|
23
53
|
return {
|
|
24
54
|
exitCode: r.exitCode,
|
|
25
|
-
|
|
55
|
+
// A build that emitted no parsable event still said something on stdout;
|
|
56
|
+
// falling back to the raw text keeps this adapter working as before.
|
|
57
|
+
output: text || String(r.stdout || "").trim(),
|
|
26
58
|
stderr: r.stderr,
|
|
59
|
+
killed: r.killed,
|
|
60
|
+
sessionId: threadId || resumeSessionId || null,
|
|
27
61
|
externalSessionPath: null,
|
|
28
62
|
};
|
|
29
63
|
},
|
|
@@ -11,9 +11,24 @@
|
|
|
11
11
|
// id,
|
|
12
12
|
// binary, executable name to look for in PATH
|
|
13
13
|
// versionFlag, flag to print the version
|
|
14
|
-
//
|
|
15
|
-
//
|
|
14
|
+
// sessions, "capture" when it can continue its own
|
|
15
|
+
// conversation; absent when every run
|
|
16
|
+
// starts cold
|
|
17
|
+
// async run({ system, prompt, cwd, env, timeoutMs,
|
|
18
|
+
// sessionKey, resumeSessionId })
|
|
19
|
+
// → { exitCode, output, sessionId?, externalSessionPath?, raw? }
|
|
16
20
|
// }
|
|
21
|
+
//
|
|
22
|
+
// The session arguments are what turn a runtime from a one-shot into a real
|
|
23
|
+
// a2a peer: `resumeSessionId` continues the conversation the peer already has,
|
|
24
|
+
// and `sessionId` comes back so the caller can store it and resume again next
|
|
25
|
+
// turn. `sessionKey` is a stable name for the exchange, for CLIs that can only
|
|
26
|
+
// find their own session again by title (opencode); the ones that hand their id
|
|
27
|
+
// straight back (claude-code, codex) ignore it.
|
|
28
|
+
//
|
|
29
|
+
// A runtime WITHOUT sessions is not shut out of a2a — the caller flattens the
|
|
30
|
+
// thread history into the prompt instead. Sessions only make that unnecessary,
|
|
31
|
+
// which is the point: a resumed peer does not re-read what it already knows.
|
|
17
32
|
|
|
18
33
|
import claudeCode from "./claude-code.js";
|
|
19
34
|
import codex from "./codex.js";
|
|
@@ -1,27 +1,106 @@
|
|
|
1
1
|
// OpenCode runtime adapter. Uses headless run:
|
|
2
2
|
// opencode run "<prompt>"
|
|
3
|
+
// opencode run --session <id> "<prompt>" continue an earlier exchange
|
|
3
4
|
// Reference: https://opencode.ai/docs/
|
|
4
5
|
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
5
8
|
import { runProcess } from "./_spawn.js";
|
|
6
9
|
|
|
10
|
+
// opencode prints an "agent · model" banner and ANSI colour even when its stdout
|
|
11
|
+
// is a pipe. Neither is part of the answer, and an a2a reply is logged verbatim
|
|
12
|
+
// — so a banner would be filed as the peer's first sentence.
|
|
13
|
+
const ANSI = /\u001b\[[0-9;]*[A-Za-z]/g;
|
|
14
|
+
const BANNER = /^>\s+\S+\s+\S\s+\S+\s*$/;
|
|
15
|
+
|
|
16
|
+
function cleanOutput(stdout) {
|
|
17
|
+
const lines = String(stdout || "").replace(ANSI, "").split("\n");
|
|
18
|
+
while (lines.length && !lines[0].trim()) lines.shift();
|
|
19
|
+
// Exactly one banner, and only when it leads: a reply that legitimately
|
|
20
|
+
// opens with a quoted line has to survive intact.
|
|
21
|
+
if (lines.length && BANNER.test(lines[0])) lines.shift();
|
|
22
|
+
return lines.join("\n").trim();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// opencode mints its own session ids and refuses one it did not create
|
|
26
|
+
// ("Session not found"), so APX cannot dictate the id the way Claude Code
|
|
27
|
+
// allows. What it CAN do is name the session on the way in (--title) and read
|
|
28
|
+
// the id back out of `session list`, which speaks JSON. One extra call, only on
|
|
29
|
+
// a thread's first turn — after that the id is on the ledger.
|
|
30
|
+
async function findSessionByTitle({ title, cwd, env }) {
|
|
31
|
+
const r = await runProcess({
|
|
32
|
+
command: "opencode",
|
|
33
|
+
args: ["session", "list", "--format", "json", "-n", "40"],
|
|
34
|
+
cwd,
|
|
35
|
+
env,
|
|
36
|
+
timeoutMs: 20000,
|
|
37
|
+
});
|
|
38
|
+
if (r.exitCode !== 0) return null;
|
|
39
|
+
let rows;
|
|
40
|
+
try {
|
|
41
|
+
rows = JSON.parse(r.stdout);
|
|
42
|
+
} catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (!Array.isArray(rows)) return null;
|
|
46
|
+
const named = rows.filter((s) => s && s.title === title);
|
|
47
|
+
// Sessions are listed across projects; prefer the one opened here.
|
|
48
|
+
const here = named.filter((s) => !cwd || !s.directory || s.directory === cwd);
|
|
49
|
+
const pick = (here.length ? here : named).sort((a, b) => (b.updated || 0) - (a.updated || 0))[0];
|
|
50
|
+
return pick?.id || null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Why the session we just opened is not in opencode's own list.
|
|
55
|
+
*
|
|
56
|
+
* Observed: inside a git checkout `run --title X` is listed and resumable;
|
|
57
|
+
* in a plain directory the run succeeds but never appears, so there is no id to
|
|
58
|
+
* resume. Saying which case this is beats a silent null — the exchange still
|
|
59
|
+
* works (APX carries the thread in the prompt), it just costs a re-read a turn.
|
|
60
|
+
*/
|
|
61
|
+
function missingSessionReason(cwd) {
|
|
62
|
+
let dir = cwd || process.cwd();
|
|
63
|
+
for (;;) {
|
|
64
|
+
if (fs.existsSync(path.join(dir, ".git"))) return "opencode did not list the session it just opened";
|
|
65
|
+
const up = path.dirname(dir);
|
|
66
|
+
if (up === dir) break;
|
|
67
|
+
dir = up;
|
|
68
|
+
}
|
|
69
|
+
return "opencode keeps no resumable session outside a git repo — the thread travels in the prompt instead";
|
|
70
|
+
}
|
|
71
|
+
|
|
7
72
|
export default {
|
|
8
73
|
id: "opencode",
|
|
9
74
|
binary: "opencode",
|
|
10
75
|
versionFlag: "--version",
|
|
76
|
+
sessions: "capture",
|
|
11
77
|
|
|
12
|
-
async run({ system, prompt, cwd, env, timeoutMs }) {
|
|
78
|
+
async run({ system, prompt, cwd, env, timeoutMs, sessionKey = null, resumeSessionId = null, mode = "code" }) {
|
|
13
79
|
const fullPrompt = system ? `${system}\n\n---\n\n${prompt}` : prompt;
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
80
|
+
const args = ["run"];
|
|
81
|
+
// `plan` is opencode's own read-only primary agent; `build` (its default)
|
|
82
|
+
// may write. A plain a2a message gets the one that only talks.
|
|
83
|
+
if (mode === "chat") args.push("--agent", "plan");
|
|
84
|
+
if (resumeSessionId) args.push("--session", resumeSessionId);
|
|
85
|
+
else if (sessionKey) args.push("--title", sessionKey);
|
|
86
|
+
args.push(fullPrompt);
|
|
87
|
+
|
|
88
|
+
const r = await runProcess({ command: "opencode", args, cwd, env, timeoutMs });
|
|
89
|
+
|
|
90
|
+
let sessionId = resumeSessionId || null;
|
|
91
|
+
let sessionNote = null;
|
|
92
|
+
if (!sessionId && sessionKey && r.exitCode === 0) {
|
|
93
|
+
sessionId = await findSessionByTitle({ title: sessionKey, cwd, env });
|
|
94
|
+
if (!sessionId) sessionNote = missingSessionReason(cwd);
|
|
95
|
+
}
|
|
96
|
+
|
|
21
97
|
return {
|
|
22
98
|
exitCode: r.exitCode,
|
|
23
|
-
output: r.stdout
|
|
99
|
+
output: cleanOutput(r.stdout),
|
|
24
100
|
stderr: r.stderr,
|
|
101
|
+
killed: r.killed,
|
|
102
|
+
sessionId,
|
|
103
|
+
sessionNote,
|
|
25
104
|
externalSessionPath: null,
|
|
26
105
|
};
|
|
27
106
|
},
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { runProcess } from "./_spawn.js";
|
|
2
|
+
import { detectAll } from "./detect.js";
|
|
3
|
+
|
|
4
|
+
// Did the runtime actually do the work, and if not, what does the user need to
|
|
5
|
+
// hear? Shared by every caller that spawns a CLI — the super-agent's
|
|
6
|
+
// `call_runtime` tool and the a2a peer reply — because "exit 0 with nothing on
|
|
7
|
+
// stdout" has to mean the same thing on both paths. A second copy of this
|
|
8
|
+
// judgement is how one caller starts reporting a logged-out CLI as success.
|
|
9
|
+
|
|
10
|
+
// A CLI that refuses to work says why in one line — "Not logged in · Please run
|
|
11
|
+
// /login", "usage limit reached", "model requires a newer version". That line is
|
|
12
|
+
// the whole diagnosis, and an `exit 1` that drops it leaves the model, the
|
|
13
|
+
// session record and the daemon log all equally blind. Prefer stderr (where
|
|
14
|
+
// CLIs put refusals), fall back to stdout (claude -p puts them in .result).
|
|
15
|
+
// A machine-readable runtime answers in JSON; pasting the envelope would bury
|
|
16
|
+
// the sentence inside it, so unwrap the field that carries the message.
|
|
17
|
+
// Lines that carry a diagnosis rather than the machinery around it.
|
|
18
|
+
const STACK_FRAME = /^(at\s|\.\.\.\s|Node\.js v)/;
|
|
19
|
+
const DIAGNOSIS = /(error|failed|denied|invalid|expired|not logged|log ?in|usage limit|quota|unauthor|forbidden|not found|missing|required)/i;
|
|
20
|
+
|
|
21
|
+
export function diagnosticLine(r) {
|
|
22
|
+
const pick = String(r?.stderr || "").trim() || String(r?.output || "").trim();
|
|
23
|
+
if (!pick) return "";
|
|
24
|
+
// A crashing CLI ends on `at async main (…cli.js:539307:5)`, which says
|
|
25
|
+
// nothing. Prefer the last line that reads like a cause; a stack frame is
|
|
26
|
+
// never one, and blindly taking the last line reported a 401 as a file path.
|
|
27
|
+
const lines = pick.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
28
|
+
const meaningful = lines.filter((l) => !STACK_FRAME.test(l));
|
|
29
|
+
const line =
|
|
30
|
+
meaningful.filter((l) => DIAGNOSIS.test(l)).pop() ||
|
|
31
|
+
meaningful.pop() ||
|
|
32
|
+
lines.pop() ||
|
|
33
|
+
"";
|
|
34
|
+
if (line.startsWith("{")) {
|
|
35
|
+
try {
|
|
36
|
+
const o = JSON.parse(line);
|
|
37
|
+
const msg = o.result || o.error?.message || o.error || o.message;
|
|
38
|
+
if (typeof msg === "string" && msg.trim()) return msg.trim().slice(0, 160);
|
|
39
|
+
} catch { /* not JSON after all — fall through to the raw line */ }
|
|
40
|
+
}
|
|
41
|
+
return line.slice(0, 160);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Decide if the runtime actually did the work the caller asked for. A spawn
|
|
45
|
+
// failure (-1), a non-zero exit, or a clean exit with no captured output and
|
|
46
|
+
// no transcript path all point at "process didn't really run" — exactly the
|
|
47
|
+
// false-positive scenario this guard exists to catch.
|
|
48
|
+
export function runtimeLooksLikeFailure(r, { timedOut = false, timeoutS = 0 } = {}) {
|
|
49
|
+
if (!r) return { failed: true, reason: "no runtime result" };
|
|
50
|
+
if (r.exitCode === -1 || r.error) {
|
|
51
|
+
return { failed: true, reason: r.error || "spawn error" };
|
|
52
|
+
}
|
|
53
|
+
// Order matters: we SIGTERM'd it ourselves, so whatever it exits with is our
|
|
54
|
+
// own signal echoed back. Reading that as the CLI's verdict would report a
|
|
55
|
+
// timeout as a crash — or, when the exit code is null, as "empty output".
|
|
56
|
+
// `r.killed` only arrives from adapters that bother to forward it; the clock
|
|
57
|
+
// is what every runtime has in common, so it decides.
|
|
58
|
+
if (timedOut || r.killed) {
|
|
59
|
+
return { failed: true, reason: `killed (timeout after ${timeoutS}s)` };
|
|
60
|
+
}
|
|
61
|
+
if (typeof r.exitCode === "number" && r.exitCode !== 0) {
|
|
62
|
+
const why = diagnosticLine(r);
|
|
63
|
+
return { failed: true, reason: why ? `exit ${r.exitCode}: ${why}` : `exit ${r.exitCode}` };
|
|
64
|
+
}
|
|
65
|
+
const out = String(r.output || "").trim();
|
|
66
|
+
const stderr = String(r.stderr || "").trim();
|
|
67
|
+
if (!out && !r.externalSessionPath && !r.sessionId) {
|
|
68
|
+
return {
|
|
69
|
+
failed: true,
|
|
70
|
+
reason: stderr ? `empty output (stderr: ${stderr.slice(0, 120)})` : "empty output",
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return { failed: false };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// How long we wait for `<binary> --version` before giving up on the answer.
|
|
77
|
+
// Not how long we wait for the runtime itself — that is the caller's timeout.
|
|
78
|
+
export const PROBE_TIMEOUT_MS = 3000;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Can this runtime run at all? Answered BEFORE spawning it for real, because
|
|
82
|
+
* "spawn error" is a useless thing to tell someone whose CLI is simply not
|
|
83
|
+
* installed. Shared with the super-agent's call_runtime tool so a missing
|
|
84
|
+
* binary reads the same however it was reached.
|
|
85
|
+
*/
|
|
86
|
+
export async function runtimeAvailability(runtime, rt, { probeTimeoutMs = PROBE_TIMEOUT_MS } = {}) {
|
|
87
|
+
const probe = await runProcess({
|
|
88
|
+
command: rt.binary,
|
|
89
|
+
args: rt.versionFlag ? [rt.versionFlag] : ["--version"],
|
|
90
|
+
timeoutMs: probeTimeoutMs,
|
|
91
|
+
});
|
|
92
|
+
if (probe.exitCode === 0 || probe.stdout || probe.stderr) {
|
|
93
|
+
return { ok: true };
|
|
94
|
+
}
|
|
95
|
+
// A probe WE killed is not evidence of absence — it is evidence of presence.
|
|
96
|
+
// A binary that is not there fails at spawn (ENOENT, exitCode -1) and never
|
|
97
|
+
// gets far enough to be killed, so `killed` can only mean the binary exists,
|
|
98
|
+
// started, and was slower than our clock. Under load `--version` really does
|
|
99
|
+
// take longer than three seconds, and reading that as "not installed" refused
|
|
100
|
+
// to run a CLI sitting right there — then fell into detectAll() below, which
|
|
101
|
+
// spawns EVERY coding CLI on the machine to reach a verdict we already had.
|
|
102
|
+
if (probe.killed) {
|
|
103
|
+
return { ok: true };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const detected = await detectAll();
|
|
107
|
+
const current = detected.find((d) => d.id === runtime || d.binary === rt.binary);
|
|
108
|
+
if (current?.installed) {
|
|
109
|
+
return { ok: true, detected };
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
ok: false,
|
|
113
|
+
reason: current?.reason || `${rt.binary} not found`,
|
|
114
|
+
detected,
|
|
115
|
+
installed: detected
|
|
116
|
+
.filter((d) => d.category === "runtime" && d.installed)
|
|
117
|
+
.map((d) => d.id),
|
|
118
|
+
};
|
|
119
|
+
}
|