@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
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// Group chat = owner + N project agents in one room. A group is a THREAD on the
|
|
2
|
+
// message ledger (channel "group"), so it lists and opens through the same
|
|
3
|
+
// endpoints as a2a threads: `GET /super-agent/threads` (list, in conversations.js)
|
|
4
|
+
// and `GET /super-agent/threads/group/:id` (detail). This router owns only what
|
|
5
|
+
// those don't: creating a room, adding a participant, and running the owner's
|
|
6
|
+
// turn as a streamed mention-cascade.
|
|
7
|
+
//
|
|
8
|
+
// POST /projects/:pid/groups create { title, participants } → { id }
|
|
9
|
+
// POST /projects/:pid/groups/:gid/participants add an agent { slug }
|
|
10
|
+
// POST /projects/:pid/groups/:gid/message/stream owner speaks → NDJSON cascade
|
|
11
|
+
//
|
|
12
|
+
// The cascade registers in active-turns like every other turn, keyed as the
|
|
13
|
+
// thread it is (project + channel "group" + room id), so `POST
|
|
14
|
+
// /projects/:pid/turns/abort { channel: "group", thread_id }` can stop it. It
|
|
15
|
+
// had no such record, which meant the one turn shape that can run ten agent
|
|
16
|
+
// replies off a single line was the one nobody could interrupt.
|
|
17
|
+
import { readAgents } from "#core/apc/parser.js";
|
|
18
|
+
import {
|
|
19
|
+
createGroupThread, addGroupParticipant, removeGroupParticipant, readProjectGroupThread, truncateGroupThread,
|
|
20
|
+
lastGroupOwnerMedia, GROUP_CHANNEL,
|
|
21
|
+
} from "#core/stores/messages.js";
|
|
22
|
+
import { runGroupTurn } from "#core/agent/group/run-group-turn.js";
|
|
23
|
+
import { readTurnAttachments } from "./media.js";
|
|
24
|
+
import { startActiveTurn, endActiveTurn, threadTurnKey } from "../active-turns.js";
|
|
25
|
+
import { wasAborted } from "./turn-abort.js";
|
|
26
|
+
import { asyncRoute } from "./shared.js";
|
|
27
|
+
|
|
28
|
+
const KEEPALIVE_MS = 15000;
|
|
29
|
+
|
|
30
|
+
// Best-effort owner display name for the transcript: the Telegram roster entry
|
|
31
|
+
// tagged role "owner", else a neutral fallback.
|
|
32
|
+
function ownerName(config) {
|
|
33
|
+
const owner = (config?.telegram?.contacts || []).find((c) => c.role === "owner");
|
|
34
|
+
return owner?.name || "Owner";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function register(api, { projects, project, config, plugins, registries }) {
|
|
38
|
+
api.post("/projects/:pid/groups", (req, res) => {
|
|
39
|
+
const p = project(req, res);
|
|
40
|
+
if (!p) return;
|
|
41
|
+
const { title, participants, members } = req.body || {};
|
|
42
|
+
|
|
43
|
+
// Cross-project rooms (inbox / mobile): `members: [{ project_id, slug }]`.
|
|
44
|
+
// Same-project rooms keep the old `participants: string[]` shape.
|
|
45
|
+
let slugs = [];
|
|
46
|
+
let homes = null;
|
|
47
|
+
if (Array.isArray(members) && members.length) {
|
|
48
|
+
const seen = new Set();
|
|
49
|
+
homes = {};
|
|
50
|
+
for (const m of members) {
|
|
51
|
+
const slug = typeof m?.slug === "string" ? m.slug.trim() : "";
|
|
52
|
+
if (!slug || seen.has(slug)) continue;
|
|
53
|
+
const homeId = m.project_id ?? p.id;
|
|
54
|
+
let home;
|
|
55
|
+
try { home = projects.get(homeId); } catch { home = null; }
|
|
56
|
+
if (!home?.path) continue;
|
|
57
|
+
if (!readAgents(home.path).some((a) => a.slug === slug)) continue;
|
|
58
|
+
seen.add(slug);
|
|
59
|
+
slugs.push(slug);
|
|
60
|
+
homes[slug] = home.id;
|
|
61
|
+
}
|
|
62
|
+
// All members live on the host project → no homes map needed.
|
|
63
|
+
if (slugs.length && Object.values(homes).every((id) => String(id) === String(p.id))) {
|
|
64
|
+
homes = null;
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
const known = new Set(readAgents(p.path).map((a) => a.slug));
|
|
68
|
+
slugs = (Array.isArray(participants) ? participants : []).filter((s) => known.has(s));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (slugs.length < 1) return res.status(400).json({ error: "at least one existing agent required" });
|
|
72
|
+
try {
|
|
73
|
+
const id = createGroupThread(p.logMessage, { title: title || null, participants: slugs, homes });
|
|
74
|
+
try { projects.rebuild(p.id); } catch { /* best-effort */ }
|
|
75
|
+
res.status(201).json({
|
|
76
|
+
id, channel: "group", title: title || slugs.join(" · "), participants: slugs,
|
|
77
|
+
...(homes ? { homes } : {}),
|
|
78
|
+
});
|
|
79
|
+
} catch (e) {
|
|
80
|
+
res.status(400).json({ error: e.message });
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
api.post("/projects/:pid/groups/:gid/participants", (req, res) => {
|
|
85
|
+
const p = project(req, res);
|
|
86
|
+
if (!p) return;
|
|
87
|
+
const { slug } = req.body || {};
|
|
88
|
+
if (!readAgents(p.path).some((a) => a.slug === slug))
|
|
89
|
+
return res.status(404).json({ error: "agent not found" });
|
|
90
|
+
const thread = readProjectGroupThread(p.storagePath, req.params.gid);
|
|
91
|
+
if (!thread) return res.status(404).json({ error: "group not found" });
|
|
92
|
+
if (!thread.participants.includes(slug)) {
|
|
93
|
+
addGroupParticipant(p.logMessage, req.params.gid, [...thread.participants, slug], slug);
|
|
94
|
+
try { projects.rebuild(p.id); } catch { /* best-effort */ }
|
|
95
|
+
}
|
|
96
|
+
res.json({ id: req.params.gid, participants: [...new Set([...thread.participants, slug])] });
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Remove an agent from a room. Records a "… salió del chat" notice and drops
|
|
100
|
+
// them from the roster, so the cascade no longer seeds or lists them.
|
|
101
|
+
api.delete("/projects/:pid/groups/:gid/participants/:slug", (req, res) => {
|
|
102
|
+
const p = project(req, res);
|
|
103
|
+
if (!p) return;
|
|
104
|
+
const thread = readProjectGroupThread(p.storagePath, req.params.gid);
|
|
105
|
+
if (!thread) return res.status(404).json({ error: "group not found" });
|
|
106
|
+
const next = thread.participants.filter((s) => s !== req.params.slug);
|
|
107
|
+
if (next.length !== thread.participants.length) {
|
|
108
|
+
removeGroupParticipant(p.logMessage, req.params.gid, req.params.slug, next);
|
|
109
|
+
try { projects.rebuild(p.id); } catch { /* best-effort */ }
|
|
110
|
+
}
|
|
111
|
+
res.json({ id: req.params.gid, participants: next });
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Rewind a group so a regenerate/edit can overwrite everything after a point.
|
|
115
|
+
// `keep_visible` = how many pane bubbles to keep (tools + consecutive same
|
|
116
|
+
// speaker collapse like the web transcript).
|
|
117
|
+
api.post("/projects/:pid/groups/:gid/truncate", (req, res) => {
|
|
118
|
+
const p = project(req, res);
|
|
119
|
+
if (!p) return;
|
|
120
|
+
const keepVisible = Number(req.body?.keep_visible);
|
|
121
|
+
if (!Number.isInteger(keepVisible) || keepVisible < 0)
|
|
122
|
+
return res.status(400).json({ error: "keep_visible must be a non-negative integer" });
|
|
123
|
+
if (!readProjectGroupThread(p.storagePath, req.params.gid))
|
|
124
|
+
return res.status(404).json({ error: "group not found" });
|
|
125
|
+
const out = truncateGroupThread(p.storagePath, req.params.gid, keepVisible);
|
|
126
|
+
try { projects.rebuild(p.id); } catch { /* best-effort */ }
|
|
127
|
+
res.json({ ok: true, ...out });
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// The owner speaks; the room answers as an NDJSON cascade of speaker events.
|
|
131
|
+
// `rerun: true` re-runs against the existing last owner message (regenerate).
|
|
132
|
+
// Optional `from` resumes the cascade at that speaker so earlier replies
|
|
133
|
+
// this turn stay put; without it the whole room-answer is re-run.
|
|
134
|
+
api.post("/projects/:pid/groups/:gid/message/stream", asyncRoute(async (req, res) => {
|
|
135
|
+
const p = project(req, res);
|
|
136
|
+
if (!p) return;
|
|
137
|
+
const { prompt, rerun, attachments, from, reason } = req.body || {};
|
|
138
|
+
if (!readProjectGroupThread(p.storagePath, req.params.gid)) return res.status(404).json({ error: "group not found" });
|
|
139
|
+
// Files the composer uploaded to ~/.apx/media: images ride on each speaker's
|
|
140
|
+
// turn (vision), and a marker naming each file is folded into the prompt so a
|
|
141
|
+
// photo with no caption is still a turn and a non-vision agent is told a file
|
|
142
|
+
// arrived and where it lives. Same handling as the 1:1 chat.
|
|
143
|
+
//
|
|
144
|
+
// On a REGENERATE (rerun), the owner already sent the turn — re-read the
|
|
145
|
+
// photo it carried from the ledger and re-attach it, or the re-run agents
|
|
146
|
+
// lose sight of the image the original turn answered.
|
|
147
|
+
const rerunAttach = rerun
|
|
148
|
+
? (() => { const md = lastGroupOwnerMedia(p.storagePath, req.params.gid); return md ? [md] : []; })()
|
|
149
|
+
: attachments;
|
|
150
|
+
const turnFiles = readTurnAttachments(rerunAttach);
|
|
151
|
+
const turnPrompt = rerun ? "" : [...turnFiles.markers, prompt].filter(Boolean).join(" ");
|
|
152
|
+
if (!rerun && !turnPrompt.trim()) return res.status(400).json({ error: "prompt required" });
|
|
153
|
+
|
|
154
|
+
res.setHeader("content-type", "application/x-ndjson; charset=utf-8");
|
|
155
|
+
res.setHeader("cache-control", "no-cache, no-transform");
|
|
156
|
+
res.setHeader("x-accel-buffering", "no");
|
|
157
|
+
res.flushHeaders?.();
|
|
158
|
+
|
|
159
|
+
let lastWriteAt = Date.now();
|
|
160
|
+
const send = (event) => { lastWriteAt = Date.now(); res.write(JSON.stringify(event) + "\n"); };
|
|
161
|
+
const keepalive = setInterval(() => {
|
|
162
|
+
if (Date.now() - lastWriteAt < KEEPALIVE_MS) return;
|
|
163
|
+
lastWriteAt = Date.now();
|
|
164
|
+
try { res.write("\n"); } catch { /* socket gone */ }
|
|
165
|
+
}, KEEPALIVE_MS);
|
|
166
|
+
keepalive.unref?.();
|
|
167
|
+
res.on("close", () => clearInterval(keepalive));
|
|
168
|
+
|
|
169
|
+
// The room's kill switch. A cascade is the longest-running turn shape the
|
|
170
|
+
// daemon has — one owner line can fan out into MAX_TURNS_PER_MESSAGE full
|
|
171
|
+
// tool loops — and until this record existed the Stop button could only
|
|
172
|
+
// close the browser's socket while the room kept working and kept writing.
|
|
173
|
+
// Closing the socket deliberately does not stop the run (that is what lets
|
|
174
|
+
// another tab catch up), so stopping is asked for out loud, through
|
|
175
|
+
// POST /projects/:pid/turns/abort, which reaches `abort` here.
|
|
176
|
+
const turnAbort = new AbortController();
|
|
177
|
+
const active = startActiveTurn(threadTurnKey(p.id, GROUP_CHANNEL, req.params.gid), {
|
|
178
|
+
project_id: p.id,
|
|
179
|
+
channel: GROUP_CHANNEL,
|
|
180
|
+
thread_id: req.params.gid,
|
|
181
|
+
abort: () => turnAbort.abort(),
|
|
182
|
+
});
|
|
183
|
+
send({ type: "start", turn_id: active.id, channel: GROUP_CHANNEL, thread_id: req.params.gid });
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
await runGroupTurn({
|
|
187
|
+
p, gid: req.params.gid, text: turnPrompt, rerun: !!rerun,
|
|
188
|
+
from: typeof from === "string" && from.trim() ? from.trim() : null,
|
|
189
|
+
reason: typeof reason === "string" && reason.trim() ? reason.trim() : null,
|
|
190
|
+
attachments: turnFiles.attachments, media: turnFiles.media,
|
|
191
|
+
ownerName: ownerName(config), config, projects, plugins, registries,
|
|
192
|
+
signal: turnAbort.signal,
|
|
193
|
+
onEvent: send,
|
|
194
|
+
});
|
|
195
|
+
try { projects.rebuild(p.id); } catch { /* best-effort */ }
|
|
196
|
+
// Stopped, not broken. runGroupTurn persists the interrupted speaker's
|
|
197
|
+
// partial and returns normally, so the room is consistent either way; the
|
|
198
|
+
// client only needs to know which of the two happened. `aborted` rather
|
|
199
|
+
// than `error` for the same reason the 1:1 stream draws the line there —
|
|
200
|
+
// a client that paints errors red must not accuse the daemon of breaking
|
|
201
|
+
// every time the owner presses Stop.
|
|
202
|
+
const stopped = turnAbort.signal.aborted;
|
|
203
|
+
send(stopped ? { type: "aborted" } : { type: "final" });
|
|
204
|
+
clearInterval(keepalive);
|
|
205
|
+
res.end();
|
|
206
|
+
} catch (e) {
|
|
207
|
+
try { projects.rebuild(p.id); } catch { /* best-effort */ }
|
|
208
|
+
send(wasAborted(e, turnAbort) ? { type: "aborted" } : { type: "error", error: e.message });
|
|
209
|
+
clearInterval(keepalive);
|
|
210
|
+
res.end();
|
|
211
|
+
} finally {
|
|
212
|
+
endActiveTurn(active.id);
|
|
213
|
+
}
|
|
214
|
+
}));
|
|
215
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Daemon HTTP routes for image generation.
|
|
2
|
+
//
|
|
3
|
+
// POST /images/generate { prompt, provider?, width?, height?, size?,
|
|
4
|
+
// steps?, cfg_scale?, seed?, sampler?, scheduler?,
|
|
5
|
+
// count?, format?, negative_prompt?, model?,
|
|
6
|
+
// init_image?, denoising_strength?,
|
|
7
|
+
// control_image?, control_strength? }
|
|
8
|
+
// init_image / control_image are base64 (bare or a
|
|
9
|
+
// data: URL). They are two different operations —
|
|
10
|
+
// repaint this canvas vs. keep this structure — and
|
|
11
|
+
// no engine accepts both. Bodies are capped at 2 MB
|
|
12
|
+
// by the express json parser. The echoed `request`
|
|
13
|
+
// has the payloads replaced by a size marker.
|
|
14
|
+
// → { images: [{path, url, bytes, mime, seed}],
|
|
15
|
+
// provider, model, request, ignored, elapsed_ms }
|
|
16
|
+
//
|
|
17
|
+
// GET /images/providers → { configured_provider, mode, order, defaults,
|
|
18
|
+
// engines: [{id, available, configured, …}] }
|
|
19
|
+
//
|
|
20
|
+
// GET /images/capabilities?provider=<id>
|
|
21
|
+
// → { provider, capabilities: {models, samplers, …} }
|
|
22
|
+
//
|
|
23
|
+
// GET /images/file?path=<abs>
|
|
24
|
+
// → the bytes, sandboxed to ~/.apx/images
|
|
25
|
+
//
|
|
26
|
+
// Glue only: every decision (engine routing, defaults, where files land) lives
|
|
27
|
+
// in core/images/. `url` is added here because it is a transport concern —
|
|
28
|
+
// core has no idea an HTTP client will need a way to fetch the file back.
|
|
29
|
+
import fs from "node:fs/promises";
|
|
30
|
+
import path from "node:path";
|
|
31
|
+
import { IMAGES_DIR } from "#core/config/paths.js";
|
|
32
|
+
import { readConfig } from "#core/config/index.js";
|
|
33
|
+
import { generate, listProviders, capabilities } from "#core/images/generate.js";
|
|
34
|
+
import { apiPath } from "./prefix.js";
|
|
35
|
+
import { asyncRoute } from "./shared.js";
|
|
36
|
+
|
|
37
|
+
/** Where a client can fetch this file from. Absolute paths stay server-side. */
|
|
38
|
+
function fileUrl(absPath) {
|
|
39
|
+
return `${apiPath("/images/file")}?path=${encodeURIComponent(absPath)}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function register(api) {
|
|
43
|
+
api.post("/images/generate", asyncRoute(async (req, res) => {
|
|
44
|
+
const body = req.body || {};
|
|
45
|
+
if (typeof body.prompt !== "string" || !body.prompt.trim()) {
|
|
46
|
+
return res.status(400).json({ error: "prompt required" });
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const result = await generate({ ...body, globalConfig: readConfig() });
|
|
50
|
+
res.json({
|
|
51
|
+
...result,
|
|
52
|
+
images: result.images.map((img) => ({ ...img, url: fileUrl(img.path) })),
|
|
53
|
+
});
|
|
54
|
+
} catch (e) {
|
|
55
|
+
res.status(502).json({ error: e.message });
|
|
56
|
+
}
|
|
57
|
+
}));
|
|
58
|
+
|
|
59
|
+
api.get("/images/providers", asyncRoute(async (_req, res) => {
|
|
60
|
+
try {
|
|
61
|
+
res.json(await listProviders(readConfig()));
|
|
62
|
+
} catch (e) {
|
|
63
|
+
res.status(500).json({ error: e.message });
|
|
64
|
+
}
|
|
65
|
+
}));
|
|
66
|
+
|
|
67
|
+
api.get("/images/capabilities", asyncRoute(async (req, res) => {
|
|
68
|
+
try {
|
|
69
|
+
res.json(await capabilities({
|
|
70
|
+
provider: req.query.provider ? String(req.query.provider) : undefined,
|
|
71
|
+
globalConfig: readConfig(),
|
|
72
|
+
}));
|
|
73
|
+
} catch (e) {
|
|
74
|
+
res.status(400).json({ error: e.message });
|
|
75
|
+
}
|
|
76
|
+
}));
|
|
77
|
+
|
|
78
|
+
// Sandboxed to the gallery: a path that escapes it is refused, so a leaked
|
|
79
|
+
// absolute path in a reply can never be turned into an arbitrary file read.
|
|
80
|
+
api.get("/images/file", asyncRoute(async (req, res) => {
|
|
81
|
+
const rawPath = String(req.query.path || "");
|
|
82
|
+
if (!rawPath) return res.status(400).json({ error: "path required" });
|
|
83
|
+
const root = path.resolve(IMAGES_DIR);
|
|
84
|
+
const resolved = path.resolve(rawPath);
|
|
85
|
+
if (resolved !== root && !resolved.startsWith(root + path.sep)) {
|
|
86
|
+
return res.status(403).json({ error: "path outside images dir" });
|
|
87
|
+
}
|
|
88
|
+
let bytes;
|
|
89
|
+
try {
|
|
90
|
+
bytes = await fs.readFile(resolved);
|
|
91
|
+
} catch {
|
|
92
|
+
return res.status(404).json({ error: "not found" });
|
|
93
|
+
}
|
|
94
|
+
const ext = path.extname(resolved).toLowerCase();
|
|
95
|
+
const mime =
|
|
96
|
+
ext === ".png" ? "image/png" :
|
|
97
|
+
ext === ".jpg" || ext === ".jpeg" ? "image/jpeg" :
|
|
98
|
+
ext === ".webp" ? "image/webp" :
|
|
99
|
+
ext === ".gif" ? "image/gif" :
|
|
100
|
+
"application/octet-stream";
|
|
101
|
+
res.setHeader("Content-Type", mime);
|
|
102
|
+
// Immutable content at a unique path — cache hard so a gallery of
|
|
103
|
+
// thumbnails doesn't re-read disk on every render.
|
|
104
|
+
res.setHeader("Cache-Control", "private, max-age=86400");
|
|
105
|
+
res.send(bytes);
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
@@ -4,9 +4,101 @@
|
|
|
4
4
|
// The conversation-first entry point. Project-first navigation is unaffected —
|
|
5
5
|
// this is a second axis over the same data, not a replacement for it.
|
|
6
6
|
import { listAgentInbox } from "#core/stores/agent-inbox.js";
|
|
7
|
+
import { listProjectA2AThreads, listProjectGroupThreads } from "#core/stores/messages.js";
|
|
7
8
|
import { readConfig } from "#core/config/index.js";
|
|
8
9
|
import { resolveAgentName } from "#core/identity/index.js";
|
|
9
|
-
import {
|
|
10
|
+
import { faceResolverFor, readAgentsSafe } from "./thread-faces.js";
|
|
11
|
+
import { pageEnvelope, A2A_SLUG_PREFIX, GROUP_SLUG_PREFIX } from "./shared.js";
|
|
12
|
+
import { convTurnKey, getActiveTurnByKey, listActiveTurns } from "../active-turns.js";
|
|
13
|
+
|
|
14
|
+
function activeTurnForRow(row, activeTurns) {
|
|
15
|
+
if (row.kind === "agent" && row.project_id != null && row.conversation_id) {
|
|
16
|
+
return getActiveTurnByKey(convTurnKey(row.project_id, row.conversation_id));
|
|
17
|
+
}
|
|
18
|
+
if (row.kind === "super_agent" && row.channel && row.conversation_id) {
|
|
19
|
+
return activeTurns.find((turn) =>
|
|
20
|
+
turn.channel === row.channel && turn.thread_id === row.conversation_id
|
|
21
|
+
) || null;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// a2a "group chats" aren't any single agent's conversation, so listAgentInbox
|
|
27
|
+
// (per-agent) doesn't see them. Fold each project's a2a pairs in as their own
|
|
28
|
+
// rows — this is the one place that shows EVERY conversation, so a group chat
|
|
29
|
+
// belongs here next to the individual ones.
|
|
30
|
+
//
|
|
31
|
+
// Faces and the "Andy · Claude" title come from the shared resolver in
|
|
32
|
+
// thread-faces.js, the same one the Chats sidebar and the thread header read
|
|
33
|
+
// through — this row is not where that gets decided.
|
|
34
|
+
function a2aInboxRows(entries, faces) {
|
|
35
|
+
const rows = [];
|
|
36
|
+
for (const e of entries) {
|
|
37
|
+
let threads = [];
|
|
38
|
+
try { threads = listProjectA2AThreads(e.storagePath); } catch { /* skip */ }
|
|
39
|
+
const agents = readAgentsSafe(e.path);
|
|
40
|
+
for (const raw of threads) {
|
|
41
|
+
const th = faces.decorate(raw, agents);
|
|
42
|
+
rows.push({
|
|
43
|
+
project_id: e.id,
|
|
44
|
+
project_name: e.name,
|
|
45
|
+
project_path: e.path,
|
|
46
|
+
agent_slug: `${A2A_SLUG_PREFIX }${th.id}`,
|
|
47
|
+
agent_name: th.title,
|
|
48
|
+
agent_emoji: null,
|
|
49
|
+
agent_icon: null,
|
|
50
|
+
kind: "a2a",
|
|
51
|
+
participants: th.participants,
|
|
52
|
+
participant_faces: th.participant_faces,
|
|
53
|
+
...(th.requested_by ? { requested_by: th.requested_by } : {}),
|
|
54
|
+
pinned: false,
|
|
55
|
+
conversation_id: th.id,
|
|
56
|
+
channel: "a2a",
|
|
57
|
+
messages: th.messages,
|
|
58
|
+
preview: th.preview || null,
|
|
59
|
+
preview_at: th.preview_at || null,
|
|
60
|
+
last_activity_at: th.last_ts,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return rows;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Group rooms (owner + N agents) are threads on the ledger, same as a2a — fold
|
|
68
|
+
// them in here too so the one place that shows EVERY conversation shows them.
|
|
69
|
+
// Shaped exactly like an a2a row (kind "group") so the frontend reuses the same
|
|
70
|
+
// multi-face rendering and thread-selection it already has for a2a.
|
|
71
|
+
function groupInboxRows(entries, faces) {
|
|
72
|
+
const rows = [];
|
|
73
|
+
for (const e of entries) {
|
|
74
|
+
let threads = [];
|
|
75
|
+
try { threads = listProjectGroupThreads(e.storagePath); } catch { /* skip */ }
|
|
76
|
+
const agents = readAgentsSafe(e.path);
|
|
77
|
+
for (const raw of threads) {
|
|
78
|
+
const th = faces.decorate(raw, agents);
|
|
79
|
+
rows.push({
|
|
80
|
+
project_id: e.id,
|
|
81
|
+
project_name: e.name,
|
|
82
|
+
project_path: e.path,
|
|
83
|
+
agent_slug: `${GROUP_SLUG_PREFIX}${th.id}`,
|
|
84
|
+
agent_name: th.title,
|
|
85
|
+
agent_emoji: null,
|
|
86
|
+
agent_icon: null,
|
|
87
|
+
kind: "group",
|
|
88
|
+
participants: th.participants,
|
|
89
|
+
participant_faces: th.participant_faces,
|
|
90
|
+
pinned: false,
|
|
91
|
+
conversation_id: th.id,
|
|
92
|
+
channel: "group",
|
|
93
|
+
messages: th.messages,
|
|
94
|
+
preview: th.preview || null,
|
|
95
|
+
preview_at: th.preview_at || null,
|
|
96
|
+
last_activity_at: th.last_ts,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return rows;
|
|
101
|
+
}
|
|
10
102
|
|
|
11
103
|
export function register(api, { projects }) {
|
|
12
104
|
api.get("/inbox", (req, res) => {
|
|
@@ -23,8 +115,22 @@ export function register(api, { projects }) {
|
|
|
23
115
|
});
|
|
24
116
|
}
|
|
25
117
|
|
|
118
|
+
// `?channel=web` scopes the individual-agent rows to one channel — the
|
|
119
|
+
// inbox and the phone are web-only so a Telegram thread never surfaces
|
|
120
|
+
// there. a2a group rows are their own channel and are added below,
|
|
121
|
+
// unaffected by this filter.
|
|
122
|
+
const channel = typeof req.query.channel === "string" && req.query.channel
|
|
123
|
+
? req.query.channel
|
|
124
|
+
: null;
|
|
125
|
+
|
|
26
126
|
const { rows, skipped } = listAgentInbox(entries, {
|
|
27
127
|
includeEmpty: req.query.include_empty === "1" || req.query.include_empty === "true",
|
|
128
|
+
channel,
|
|
129
|
+
// No `?channel=` means "show me everything", and everything now means
|
|
130
|
+
// one row per channel rather than one row per agent wearing whichever
|
|
131
|
+
// channel happened to speak last. Asking for a single channel already
|
|
132
|
+
// answers the question, so it keeps the one-row-per-agent shape.
|
|
133
|
+
perChannel: !channel,
|
|
28
134
|
});
|
|
29
135
|
|
|
30
136
|
// The super-agent's display name lives in identity.json, and core must not
|
|
@@ -35,7 +141,22 @@ export function register(api, { projects }) {
|
|
|
35
141
|
r.kind === "super_agent" ? { ...r, agent_name: r.agent_name || superName } : r
|
|
36
142
|
);
|
|
37
143
|
|
|
38
|
-
|
|
144
|
+
// Faces and titles for the multi-agent rows: one resolver for the request,
|
|
145
|
+
// shared with the Chats sidebar and the thread header (thread-faces.js).
|
|
146
|
+
// It knows the super-agent's own face too, so "golf-coach ↔ Roby" shows
|
|
147
|
+
// Roby with an avatar instead of the bare `super_agent` slug.
|
|
148
|
+
const faces = faceResolverFor(projects);
|
|
149
|
+
|
|
150
|
+
// Merge a2a group chats in and re-sort so the newest conversation wins
|
|
151
|
+
// regardless of whether it was an individual or a group one.
|
|
152
|
+
const activeTurns = listActiveTurns();
|
|
153
|
+
const merged = [...named, ...a2aInboxRows(entries, faces), ...groupInboxRows(entries, faces)]
|
|
154
|
+
.map((row) => ({ ...row, active_turn: activeTurnForRow(row, activeTurns) }))
|
|
155
|
+
.sort(
|
|
156
|
+
(a, b) => new Date(b.last_activity_at || 0).getTime() - new Date(a.last_activity_at || 0).getTime()
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const envelope = pageEnvelope(merged, req.query);
|
|
39
160
|
if (skipped.length) envelope.meta = { ...(envelope.meta || {}), skipped };
|
|
40
161
|
res.json(envelope);
|
|
41
162
|
} catch (e) {
|
|
@@ -25,8 +25,37 @@ import {
|
|
|
25
25
|
getPluginService,
|
|
26
26
|
reconcilePluginMcp,
|
|
27
27
|
} from "#core/integrations/index.js";
|
|
28
|
+
import { verifyState, callbackUrl } from "#core/integrations/plugins/_google-oauth.js";
|
|
28
29
|
import { asyncRoute } from "./shared.js";
|
|
29
30
|
|
|
31
|
+
// The browser origin behind this request, reconstructed so an OAuth redirect URI
|
|
32
|
+
// built at authorize-time matches the one the callback trades the code with.
|
|
33
|
+
function requestOrigin(req) {
|
|
34
|
+
const proto = String(req.headers["x-forwarded-proto"] || (req.secure ? "https" : "http")).split(",")[0].trim();
|
|
35
|
+
const host = req.headers["x-forwarded-host"] || req.headers.host;
|
|
36
|
+
return `${proto}://${host}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// The little page the OAuth popup lands on: tells the opener panel it's done and
|
|
40
|
+
// closes itself. Kept self-contained (no bundle) since it renders outside the SPA.
|
|
41
|
+
function oauthResultPage(ok, message = "") {
|
|
42
|
+
const title = ok ? "Conectado ✓" : "No se pudo conectar";
|
|
43
|
+
const detail = ok ? "Ya podés cerrar esta ventana." : String(message || "Reintentá desde el panel.");
|
|
44
|
+
const safe = detail.replace(/[<>&]/g, (c) => ({ "<": "<", ">": ">", "&": "&" })[c]);
|
|
45
|
+
return `<!doctype html><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
46
|
+
<title>${title}</title>
|
|
47
|
+
<body style="margin:0;font:15px/1.5 system-ui,sans-serif;background:#0b0f14;color:#e6edf3;display:grid;place-items:center;height:100vh">
|
|
48
|
+
<div style="max-width:22rem;text-align:center;padding:1.5rem">
|
|
49
|
+
<div style="font-size:2rem;margin-bottom:.5rem">${ok ? "✅" : "⚠️"}</div>
|
|
50
|
+
<h1 style="font-size:1.05rem;margin:0 0 .35rem">${title}</h1>
|
|
51
|
+
<p style="margin:0;color:#9aa7b4">${safe}</p>
|
|
52
|
+
</div>
|
|
53
|
+
<script>
|
|
54
|
+
try { window.opener && window.opener.postMessage({ source: "apx-oauth", ok: ${ok ? "true" : "false"} }, "*"); } catch (e) {}
|
|
55
|
+
${ok ? "setTimeout(function(){ try { window.close(); } catch (e) {} }, 1200);" : ""}
|
|
56
|
+
</script>`;
|
|
57
|
+
}
|
|
58
|
+
|
|
30
59
|
// Integration scope vocabulary: project | global, accepting "default" for
|
|
31
60
|
// global and both "shared" and "runtime" for project. See the note in
|
|
32
61
|
// api/mcps.js — do not merge these three helpers.
|
|
@@ -65,6 +94,37 @@ export function register(api, { projects, project, registries }) {
|
|
|
65
94
|
}
|
|
66
95
|
}
|
|
67
96
|
|
|
97
|
+
// OAuth redirect landing. Google sends the browser here (no bearer token — see
|
|
98
|
+
// the auth allowlist in shared.js), with a signed `state` that says which
|
|
99
|
+
// plugin/project/scope started the flow. We trade the code for a refresh token
|
|
100
|
+
// and persist it, then render a page that tells the panel it's done.
|
|
101
|
+
api.get("/integrations/oauth/callback", asyncRoute(async (req, res) => {
|
|
102
|
+
const fail = (msg) => res.status(400).type("html").send(oauthResultPage(false, msg));
|
|
103
|
+
const { code, state, error } = req.query || {};
|
|
104
|
+
if (error) return fail(`Google devolvió un error: ${error}`);
|
|
105
|
+
const decoded = verifyState(state);
|
|
106
|
+
if (!decoded || !code) return fail("El enlace de autorización venció o es inválido. Reintentá desde el panel.");
|
|
107
|
+
const svc = getPluginService(decoded.slug);
|
|
108
|
+
if (!svc || typeof svc.completeOAuth !== "function") return fail(`El plugin "${decoded.slug}" no soporta OAuth.`);
|
|
109
|
+
const scope = normalizeIntegrationScope(decoded.scope) || "project";
|
|
110
|
+
const p = projects.get(Number(decoded.pid) || 0);
|
|
111
|
+
if (!p) return fail("No encontré el proyecto para guardar la conexión.");
|
|
112
|
+
const storagePath = storagePathForScope(scope, p, projects);
|
|
113
|
+
if (!storagePath) return fail("El proyecto no tiene ruta de storage.");
|
|
114
|
+
const store = new IntegrationStore(storagePath);
|
|
115
|
+
const record = store.get(decoded.slug);
|
|
116
|
+
if (!record) return fail("La integración no está configurada (¿cargaste el client_id?).");
|
|
117
|
+
try {
|
|
118
|
+
const redirectUri = callbackUrl(requestOrigin(req));
|
|
119
|
+
const { patch } = await svc.completeOAuth(record, { code: String(code), redirectUri });
|
|
120
|
+
store.upsert(decoded.slug, patch);
|
|
121
|
+
reconcileMcp(svc, storagePath, scope, p);
|
|
122
|
+
res.type("html").send(oauthResultPage(true));
|
|
123
|
+
} catch (e) {
|
|
124
|
+
fail(e.message || String(e));
|
|
125
|
+
}
|
|
126
|
+
}));
|
|
127
|
+
|
|
68
128
|
// List stored integrations in the chosen scope (secrets redacted).
|
|
69
129
|
api.get("/projects/:pid/integrations", (req, res) => {
|
|
70
130
|
const p = project(req, res);
|
|
@@ -90,6 +150,7 @@ export function register(api, { projects, project, registries }) {
|
|
|
90
150
|
const resolved = resolveIntegration({
|
|
91
151
|
projectStorage: p.storagePath,
|
|
92
152
|
slug: entry.slug,
|
|
153
|
+
defaultStorage: storagePathForScope("global", p, projects),
|
|
93
154
|
requireEnabled: false,
|
|
94
155
|
});
|
|
95
156
|
status = svc.status(resolved?.record || null);
|
|
@@ -195,8 +256,9 @@ export function register(api, { projects, project, registries }) {
|
|
|
195
256
|
if (!record) return res.status(404).json({ error: "integration not configured" });
|
|
196
257
|
try {
|
|
197
258
|
// Actions get a 2nd ctx arg (existing plugins ignore it). Obsidian's
|
|
198
|
-
// sync_memory uses it to reach every project's memory.md
|
|
199
|
-
|
|
259
|
+
// sync_memory uses it to reach every project's memory.md; calendar's
|
|
260
|
+
// authorize uses `origin` to build the OAuth redirect URI.
|
|
261
|
+
const actionCtx = { storagePath, scope, project: p, projects, registries, origin: requestOrigin(req) };
|
|
200
262
|
res.json(await fn.call(svc.actions, record, actionCtx));
|
|
201
263
|
} catch (e) {
|
|
202
264
|
res.status(400).json({ error: e.message });
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
// POST /projects/:pid/mcps/:name/call
|
|
10
10
|
import fs from "node:fs";
|
|
11
11
|
import path from "node:path";
|
|
12
|
+
import { asyncRoute } from "./shared.js";
|
|
12
13
|
import {
|
|
13
14
|
readApfMcps,
|
|
14
15
|
writeApfMcps,
|
|
@@ -198,7 +199,7 @@ export function register(api, { projects, registries, project }) {
|
|
|
198
199
|
// Full tool catalog — tools/list with input schemas, all pages merged.
|
|
199
200
|
// This is what `apx mcp tools` renders; /test below stays as the
|
|
200
201
|
// lightweight smoke check for the web UI card.
|
|
201
|
-
api.get("/projects/:pid/mcps/:name/tools", async (req, res) => {
|
|
202
|
+
api.get("/projects/:pid/mcps/:name/tools", asyncRoute(async (req, res) => {
|
|
202
203
|
const p = project(req, res);
|
|
203
204
|
if (!p) return;
|
|
204
205
|
try {
|
|
@@ -207,9 +208,9 @@ export function register(api, { projects, registries, project }) {
|
|
|
207
208
|
} catch (e) {
|
|
208
209
|
res.status(500).json({ error: e.message });
|
|
209
210
|
}
|
|
210
|
-
});
|
|
211
|
+
}));
|
|
211
212
|
|
|
212
|
-
api.post("/projects/:pid/mcps/:name/call", async (req, res) => {
|
|
213
|
+
api.post("/projects/:pid/mcps/:name/call", asyncRoute(async (req, res) => {
|
|
213
214
|
const p = project(req, res);
|
|
214
215
|
if (!p) return;
|
|
215
216
|
const { tool, params } = req.body || {};
|
|
@@ -220,12 +221,12 @@ export function register(api, { projects, registries, project }) {
|
|
|
220
221
|
} catch (e) {
|
|
221
222
|
res.status(500).json({ error: e.message });
|
|
222
223
|
}
|
|
223
|
-
});
|
|
224
|
+
}));
|
|
224
225
|
|
|
225
226
|
// Smoke test — calls tools/list and reports either the tool catalog or a
|
|
226
227
|
// clean error message. Used by the "Test" button in the MCP card so the
|
|
227
228
|
// user can sanity-check a freshly-saved MCP without firing a real tool.
|
|
228
|
-
api.post("/projects/:pid/mcps/:name/test", async (req, res) => {
|
|
229
|
+
api.post("/projects/:pid/mcps/:name/test", asyncRoute(async (req, res) => {
|
|
229
230
|
const p = project(req, res);
|
|
230
231
|
if (!p) return;
|
|
231
232
|
try {
|
|
@@ -242,7 +243,7 @@ export function register(api, { projects, registries, project }) {
|
|
|
242
243
|
} catch (e) {
|
|
243
244
|
res.status(200).json({ ok: false, error: e.message });
|
|
244
245
|
}
|
|
245
|
-
});
|
|
246
|
+
}));
|
|
246
247
|
|
|
247
248
|
// In-memory log buffer for one MCP — stderr tail (stdio) or fetch summary
|
|
248
249
|
// (http) plus a ring of recent events.
|