@agentprojectcontext/apx 1.81.0 → 1.89.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -8
- package/skills/apc-context/SKILL.md +14 -7
- package/skills/apx/SKILL.md +62 -2
- package/skills/apx-mcp/SKILL.md +42 -15
- package/src/core/agent/a2a/peers.js +161 -0
- package/src/core/agent/a2a/reply.js +379 -27
- package/src/core/agent/abort.js +25 -0
- package/src/core/agent/agent-model.js +58 -0
- package/src/core/agent/agent-tools.js +101 -0
- package/src/core/agent/author-line.js +110 -0
- package/src/core/agent/build-agent-system.js +52 -18
- package/src/core/agent/channels/voice-context.js +17 -2
- package/src/core/agent/closing-floor.js +117 -0
- package/src/core/agent/constants.js +119 -11
- package/src/core/agent/engine-call.js +56 -0
- package/src/core/agent/group/run-group-turn.js +218 -0
- package/src/core/agent/group/turn-resolver.js +165 -0
- package/src/core/agent/judge.js +138 -11
- package/src/core/agent/loop/side-effects.js +106 -3
- package/src/core/agent/memory.js +31 -18
- package/src/core/agent/model-capabilities.js +47 -0
- package/src/core/agent/model-router.js +11 -40
- package/src/core/agent/prompt-builder.js +47 -0
- package/src/core/agent/prompts/channels/a2a.md +12 -0
- package/src/core/agent/prompts/channels/code.md +3 -1
- package/src/core/agent/prompts/channels/telegram.md +2 -0
- package/src/core/agent/prompts/channels/web_code.md +1 -1
- package/src/core/agent/prompts/channels/whatsapp.md +37 -0
- package/src/core/agent/prompts/core/agent-base.md +2 -0
- package/src/core/agent/prompts/discipline/action.md +1 -0
- package/src/core/agent/prompts/discipline/two-segment.md +2 -1
- package/src/core/agent/prompts/modes/mobility.md +36 -0
- package/src/core/agent/retry.js +42 -0
- package/src/core/agent/run-agent.js +322 -25
- package/src/core/agent/run-turn.js +253 -0
- package/src/core/agent/self-memory.js +18 -52
- package/src/core/agent/skills/agent-skills.js +118 -0
- package/src/core/agent/skills/catalog.js +1 -1
- package/src/core/agent/skills/declared.js +13 -0
- package/src/core/agent/skills/index-store.js +8 -1
- package/src/core/agent/skills/inspector.js +20 -3
- package/src/core/agent/skills/loader.js +18 -3
- package/src/core/agent/skills/media.js +121 -0
- package/src/core/agent/skills/origin.js +61 -0
- package/src/core/agent/skills/sections.js +136 -0
- package/src/core/agent/super-agent.js +54 -14
- package/src/core/agent/tools/handlers/_calendar.js +50 -0
- package/src/core/agent/tools/handlers/add-mcp.js +103 -0
- package/src/core/agent/tools/handlers/asana-create-task.js +3 -1
- package/src/core/agent/tools/handlers/attach-media.js +56 -0
- package/src/core/agent/tools/handlers/calendar-create-event.js +38 -0
- package/src/core/agent/tools/handlers/calendar-find-slot.js +39 -0
- package/src/core/agent/tools/handlers/calendar-list-events.js +39 -0
- package/src/core/agent/tools/handlers/calendar-update-event.js +35 -0
- package/src/core/agent/tools/handlers/call-agent.js +14 -6
- package/src/core/agent/tools/handlers/call-runtime.js +27 -49
- package/src/core/agent/tools/handlers/comment-task.js +78 -0
- package/src/core/agent/tools/handlers/complete-task.js +60 -0
- package/src/core/agent/tools/handlers/configure-agent.js +70 -0
- package/src/core/agent/tools/handlers/create-agent.js +68 -0
- package/src/core/agent/tools/handlers/create-task.js +41 -3
- package/src/core/agent/tools/handlers/import-agent.js +5 -5
- package/src/core/agent/tools/handlers/list-mcp-tools.js +83 -0
- package/src/core/agent/tools/handlers/list-routines.js +46 -0
- package/src/core/agent/tools/handlers/list-tasks.js +8 -1
- package/src/core/agent/tools/handlers/mark-commitment.js +57 -0
- package/src/core/agent/tools/handlers/read-skill.js +64 -0
- package/src/core/agent/tools/handlers/remember-routine.js +2 -8
- package/src/core/agent/tools/handlers/remember.js +82 -6
- package/src/core/agent/tools/handlers/remove-agent.js +42 -0
- package/src/core/agent/tools/handlers/run-routine.js +94 -0
- package/src/core/agent/tools/handlers/run-shell.js +44 -2
- package/src/core/agent/tools/handlers/send-telegram.js +41 -19
- package/src/core/agent/tools/handlers/set-agent-prompt.js +44 -0
- package/src/core/agent/tools/handlers/view-media.js +69 -0
- package/src/core/agent/tools/handlers/write-agent-memory.js +52 -0
- package/src/core/agent/tools/helpers.js +36 -4
- package/src/core/agent/tools/names.js +64 -0
- package/src/core/agent/tools/registry-bridge.js +24 -1
- package/src/core/agent/tools/registry.js +79 -0
- package/src/core/agent/tools/tool-call-parser.js +136 -13
- package/src/core/agent/vision-bridge.js +69 -0
- package/src/core/apc/agent-identity.js +74 -0
- package/src/core/apc/agent-rename-refs.js +187 -0
- package/src/core/apc/agent-write.js +312 -0
- package/src/core/apc/agents-vault.js +1 -1
- package/src/core/apc/blob-keys.js +42 -0
- package/src/core/apc/frontmatter.js +166 -10
- package/src/core/apc/parser.js +33 -83
- package/src/core/apc/paths.js +4 -6
- package/src/core/apc/project-memory.js +44 -0
- package/src/core/apc/projects-helpers.js +33 -0
- package/src/core/apc/scaffold.js +36 -16
- package/src/core/channels/telegram/ask-callbacks.js +103 -0
- package/src/core/channels/telegram/dispatch.js +154 -30
- package/src/core/channels/telegram/helpers.js +59 -7
- package/src/core/channels/telegram/inbound/audio.js +26 -30
- package/src/core/channels/telegram/inbound/file.js +22 -32
- package/src/core/channels/telegram/inbound/photo.js +24 -28
- package/src/core/channels/telegram/progress-gate.js +76 -0
- package/src/core/channels/telegram/reply.js +151 -43
- package/src/core/channels/telegram/voice-note.js +150 -0
- package/src/core/config/index.js +53 -54
- package/src/core/config/paths.js +117 -31
- package/src/core/config/redact.js +89 -4
- package/src/core/config/secret-values.js +2 -4
- package/src/core/constants/actors.js +5 -0
- package/src/core/constants/channels.js +3 -1
- package/src/core/constants/task-categories.js +73 -0
- package/src/core/constants/task-fields.js +28 -0
- package/src/core/engines/_globs.js +33 -0
- package/src/core/engines/anthropic.js +19 -1
- package/src/core/engines/catalog.js +20 -0
- package/src/core/engines/gemini.js +84 -16
- package/src/core/engines/index.js +19 -3
- package/src/core/engines/mock.js +145 -1
- package/src/core/engines/openai-compatible.js +150 -15
- package/src/core/engines/presets.js +36 -9
- package/src/core/engines/zen.js +131 -0
- package/src/core/events/bus.js +140 -0
- package/src/core/events/mascot-notify.js +156 -0
- package/src/core/http-tools/browser.js +366 -36
- package/src/core/http-tools/catalog.js +206 -22
- package/src/core/http-tools/grep.js +62 -7
- package/src/core/http-tools/registry.js +3 -1
- package/src/core/i18n/en.js +34 -3
- package/src/core/i18n/es.js +36 -4
- package/src/core/i18n/index.js +5 -5
- package/src/core/i18n/pt.js +32 -3
- package/src/core/identity/self.js +14 -1
- package/src/core/images/engines/a1111.js +219 -0
- package/src/core/images/engines/index.js +187 -0
- package/src/core/images/engines/mock.js +74 -0
- package/src/core/images/engines/openai.js +130 -0
- package/src/core/images/engines/sdcpp.js +204 -0
- package/src/core/images/engines/shared.js +218 -0
- package/src/core/images/generate.js +260 -0
- package/src/core/integrations/catalog.js +8 -3
- package/src/core/integrations/plugins/_google-oauth.js +179 -0
- package/src/core/integrations/plugins/asana.js +7 -3
- package/src/core/integrations/plugins/calendar.js +404 -0
- package/src/core/integrations/store.js +2 -0
- package/src/core/memory/broker.js +16 -1
- package/src/core/memory/compactor.js +19 -3
- package/src/core/memory/consolidate.js +2 -2
- package/src/core/memory/dated-log.js +66 -0
- package/src/core/memory/embed-engines/custom.js +59 -0
- package/src/core/memory/embed-engines/gemini.js +9 -3
- package/src/core/memory/embed-engines/index.js +87 -15
- package/src/core/memory/embeddings.js +52 -24
- package/src/core/memory/index.js +13 -3
- package/src/core/memory/indexer.js +83 -27
- package/src/core/memory/prune.js +182 -0
- package/src/core/memory/store.js +22 -0
- package/src/core/memory/summarizer.js +72 -8
- package/src/core/mobility/answer.js +80 -0
- package/src/core/mobility/geofence.js +667 -0
- package/src/core/mobility/osm-route.js +282 -0
- package/src/core/mobility/preferences.js +91 -0
- package/src/core/mobility/state.js +245 -0
- package/src/core/mobility/trip-event.js +384 -0
- package/src/core/net/tailscale.js +168 -0
- package/src/core/profiles/bundled/secretary/PROFILE.md +32 -42
- package/src/core/profiles/bundled/secretary/config.schema.es.json +68 -0
- package/src/core/profiles/bundled/secretary/config.schema.json +30 -2
- package/src/core/profiles/bundled/secretary/profile.json +3 -1
- package/src/core/profiles/bundled/secretary/routines/a2a-sweep.json +20 -0
- package/src/core/profiles/bundled/secretary/routines/day-close.json +4 -1
- package/src/core/profiles/bundled/secretary/routines/day-open.json +7 -1
- package/src/core/profiles/bundled/secretary/routines/watch.json +13 -2
- package/src/core/profiles/lifecycle.js +243 -19
- package/src/core/profiles/paths.js +12 -0
- package/src/core/profiles/store.js +47 -0
- package/src/core/routines/active-runs.js +213 -0
- package/src/core/routines/delivery.js +612 -0
- package/src/core/routines/header.js +88 -0
- package/src/core/routines/index.js +26 -0
- package/src/core/routines/run-log.js +78 -0
- package/src/core/routines/runner.js +629 -66
- package/src/core/routines/signals.js +75 -0
- package/src/core/runtime-skills/apc-context/SKILL.md +14 -7
- package/src/core/runtime-skills/apx/SKILL.md +93 -1
- package/src/core/runtime-skills/apx-agency-agents/SKILL.md +2 -2
- package/src/core/runtime-skills/apx-agent/SKILL.md +134 -19
- package/src/core/runtime-skills/apx-commitment/SKILL.md +21 -11
- package/src/core/runtime-skills/apx-image/SKILL.md +60 -0
- package/src/core/runtime-skills/apx-integrations/SKILL.md +82 -0
- package/src/core/runtime-skills/apx-mcp/SKILL.md +45 -14
- package/src/core/runtime-skills/apx-mcp-builder/SKILL.md +4 -4
- package/src/core/runtime-skills/apx-profile/SKILL.md +27 -2
- package/src/core/runtime-skills/apx-project/SKILL.md +23 -2
- package/src/core/runtime-skills/apx-routine/SKILL.md +40 -17
- package/src/core/runtime-skills/apx-runtime/SKILL.md +124 -14
- package/src/core/runtime-skills/apx-sessions/SKILL.md +7 -6
- package/src/core/runtime-skills/apx-skill-builder/SKILL.md +15 -13
- package/src/core/runtime-skills/apx-task/SKILL.md +79 -26
- package/src/core/runtime-skills/apx-telegram/SKILL.md +12 -12
- package/src/core/runtime-skills/apx-transcribe/SKILL.md +56 -0
- package/src/core/runtime-skills/apx-voice/SKILL.md +27 -8
- package/src/core/runtime-skills/claude-code/SKILL.md +8 -0
- package/src/core/runtime-skills/openrouter/SKILL.md +8 -2
- package/src/core/runtimes/_spawn.js +9 -1
- package/src/core/runtimes/claude-code.js +11 -2
- package/src/core/runtimes/codex.js +44 -10
- package/src/core/runtimes/index.js +17 -2
- package/src/core/runtimes/opencode.js +88 -9
- package/src/core/runtimes/outcome.js +119 -0
- package/src/core/sessions/index.js +193 -1
- package/src/core/stores/agent-inbox.js +109 -23
- package/src/core/stores/code-sessions.js +21 -0
- package/src/core/stores/commitments.js +27 -3
- package/src/core/stores/conversations.js +220 -20
- package/src/core/stores/deliveries.js +177 -0
- package/src/core/stores/media-archive.js +228 -0
- package/src/core/stores/messages.js +1096 -112
- package/src/core/stores/organization.js +34 -0
- package/src/core/stores/project-memory.js +71 -0
- package/src/core/stores/routine-memory.js +16 -8
- package/src/core/stores/routines.js +27 -49
- package/src/core/stores/sessions.js +4 -8
- package/src/core/stores/tasks.js +212 -18
- package/src/core/stores/turn-record.js +209 -0
- package/src/core/tasks/columns.js +136 -0
- package/src/core/tasks/comment-turn.js +258 -0
- package/src/core/util/time.js +13 -0
- package/src/core/voice/engines/index.js +54 -1
- package/src/core/voice/engines/openai.js +50 -4
- package/src/core/voice/opus.js +67 -0
- package/src/core/voice/pronounceable.js +43 -0
- package/src/core/voice/transcription.js +4 -0
- package/src/core/voice/tts.js +114 -24
- package/src/host/daemon/active-turns.js +188 -0
- package/src/host/daemon/api/admin-config.js +9 -0
- package/src/host/daemon/api/agents.js +99 -90
- package/src/host/daemon/api/artifact-preview.js +7 -6
- package/src/host/daemon/api/artifacts.js +3 -2
- package/src/host/daemon/api/code.js +55 -9
- package/src/host/daemon/api/commitments.js +11 -0
- package/src/host/daemon/api/confirm.js +3 -2
- package/src/host/daemon/api/conversations.js +543 -35
- package/src/host/daemon/api/deck.js +9 -8
- package/src/host/daemon/api/deliveries.js +33 -0
- package/src/host/daemon/api/desktop.js +5 -4
- package/src/host/daemon/api/embeddings.js +15 -6
- package/src/host/daemon/api/engines.js +59 -8
- package/src/host/daemon/api/exec.js +437 -121
- package/src/host/daemon/api/groups.js +215 -0
- package/src/host/daemon/api/images.js +107 -0
- package/src/host/daemon/api/inbox.js +123 -2
- package/src/host/daemon/api/integrations.js +64 -2
- package/src/host/daemon/api/mcps.js +7 -6
- package/src/host/daemon/api/media.js +283 -0
- package/src/host/daemon/api/mobility.js +177 -0
- package/src/host/daemon/api/net.js +182 -0
- package/src/host/daemon/api/pairing.js +38 -5
- package/src/host/daemon/api/profiles.js +30 -2
- package/src/host/daemon/api/routines.js +36 -4
- package/src/host/daemon/api/runtimes.js +74 -39
- package/src/host/daemon/api/sessions-search.js +7 -2
- package/src/host/daemon/api/sessions.js +44 -2
- package/src/host/daemon/api/shared.js +127 -20
- package/src/host/daemon/api/skills.js +11 -4
- package/src/host/daemon/api/super-agent.js +384 -53
- package/src/host/daemon/api/tasks.js +180 -10
- package/src/host/daemon/api/telegram.js +11 -10
- package/src/host/daemon/api/thread-faces.js +159 -0
- package/src/host/daemon/api/top-level.js +3 -3
- package/src/host/daemon/api/transcribe.js +11 -10
- package/src/host/daemon/api/tts.js +97 -4
- package/src/host/daemon/api/turn-abort.js +23 -0
- package/src/host/daemon/api/turns.js +49 -0
- package/src/host/daemon/api/voice.js +5 -4
- package/src/host/daemon/api/web.js +98 -0
- package/src/host/daemon/api.js +39 -0
- package/src/host/daemon/delivery-sweep.js +58 -0
- package/src/host/daemon/desktop-ws.js +5 -23
- package/src/host/daemon/events-ws.js +273 -0
- package/src/host/daemon/index.js +59 -15
- package/src/host/daemon/plugins/desktop/index.js +17 -4
- package/src/host/daemon/plugins/telegram/index.js +78 -40
- package/src/host/daemon/pty-bridge.py +99 -0
- package/src/host/daemon/routines-scheduler.js +1 -0
- package/src/host/daemon/smoke.js +1 -2
- package/src/host/daemon/terminal-ws.js +132 -0
- package/src/host/daemon/tts-keepwarm.js +87 -0
- package/src/host/daemon/wakeup.js +11 -6
- package/src/host/daemon/whisper-server.js +44 -0
- package/src/host/daemon/whisper-server.py +70 -13
- package/src/host/daemon/ws-auth.js +28 -0
- package/src/interfaces/android/app/build.gradle +42 -0
- package/src/interfaces/android/app/proguard-rules.pro +4 -0
- package/src/interfaces/android/app/src/main/AndroidManifest.xml +139 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AlertScreen.java +139 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AndroidAutoDetector.java +106 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxCarAppService.java +57 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxPreferences.java +165 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarAlertStore.java +84 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageActionReceiver.java +47 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageNotification.java +152 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonAddress.java +35 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonClient.java +339 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DeviceLocation.java +38 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ErrandScreen.java +127 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MainActivity.java +872 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationDetector.java +63 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationListenerService.java +453 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsShareIntentParser.java +93 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotBlobCatalog.java +66 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotOverlayService.java +448 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotView.java +249 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MessageFrameParser.java +240 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/NotifyChannels.java +69 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityActionReceiver.java +78 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityNotification.java +161 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/StartupReceiver.java +57 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelEventGate.java +62 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelStatusBanner.java +116 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripLocationService.java +272 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripPlacesSheet.java +203 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripScreen.java +182 -0
- package/src/interfaces/android/app/src/main/res/drawable/app_background.xml +12 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_app.xml +10 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_launcher_foreground.xml +12 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_notification.xml +22 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_trip_car.xml +37 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/apx_logo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_amatista.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_aqua.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_brasa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_campana.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_caracol.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_carbon.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cobalto.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cometa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_coral.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cubi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_eclipse.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_faro.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_gajo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_iris.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_kiwi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_laguna.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_lila.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_menta.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_nimbo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_noche.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_onyx.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_orbita.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_ovni.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_papa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_parche.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_peon.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_perla.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_pino.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_quad.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_rubi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_saturno.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trebol.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trino.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_volcan.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_zafiro.png +0 -0
- package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
- package/src/interfaces/android/app/src/main/res/raw/apx_notification.mp3 +0 -0
- package/src/interfaces/android/app/src/main/res/values/colors.xml +4 -0
- package/src/interfaces/android/app/src/main/res/values/strings.xml +25 -0
- package/src/interfaces/android/app/src/main/res/values/styles.xml +10 -0
- package/src/interfaces/android/app/src/main/res/values-v31/styles.xml +14 -0
- package/src/interfaces/android/app/src/main/res/xml/automotive_app_desc.xml +9 -0
- package/src/interfaces/android/app/src/main/res/xml/network_security_config.xml +10 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/AndroidAutoDetectorTest.java +85 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/CarAlertStoreTest.java +104 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/DaemonAddressTest.java +23 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsNavigationDetectorTest.java +69 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsShareIntentParserTest.java +31 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MessageFrameParserTest.java +180 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TravelEventGateTest.java +64 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TripPlacesSheetTest.java +66 -0
- package/src/interfaces/android/build.gradle +3 -0
- package/src/interfaces/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/src/interfaces/android/gradle/wrapper/gradle-wrapper.properties +9 -0
- package/src/interfaces/android/gradle.properties +3 -0
- package/src/interfaces/android/gradlew +248 -0
- package/src/interfaces/android/gradlew.bat +82 -0
- package/src/interfaces/android/settings.gradle +18 -0
- package/src/interfaces/cli/commands/a2a.js +145 -4
- package/src/interfaces/cli/commands/agent.js +247 -22
- package/src/interfaces/cli/commands/code.js +1 -1
- package/src/interfaces/cli/commands/commitment.js +5 -0
- package/src/interfaces/cli/commands/config.js +85 -6
- package/src/interfaces/cli/commands/exec.js +90 -1
- package/src/interfaces/cli/commands/image.js +314 -0
- package/src/interfaces/cli/commands/mcp.js +87 -23
- package/src/interfaces/cli/commands/memory.js +35 -22
- package/src/interfaces/cli/commands/panel.js +94 -0
- package/src/interfaces/cli/commands/profile.js +14 -0
- package/src/interfaces/cli/commands/project.js +29 -0
- package/src/interfaces/cli/commands/routine.js +45 -10
- package/src/interfaces/cli/commands/runtime.js +30 -7
- package/src/interfaces/cli/commands/session.js +90 -38
- package/src/interfaces/cli/commands/sessions.js +35 -2
- package/src/interfaces/cli/commands/skills.js +15 -9
- package/src/interfaces/cli/commands/status.js +2 -3
- package/src/interfaces/cli/commands/task.js +54 -5
- package/src/interfaces/cli/commands/telegram.js +12 -4
- package/src/interfaces/cli/commands/transcribe.js +177 -0
- package/src/interfaces/cli/help/index.js +311 -72
- package/src/interfaces/cli/http.js +61 -13
- package/src/interfaces/cli/index.js +1 -1
- package/src/interfaces/cli/routes/agent.js +5 -4
- package/src/interfaces/cli/routes/commitment.js +3 -2
- package/src/interfaces/cli/routes/config.js +7 -2
- package/src/interfaces/cli/routes/image.js +11 -0
- package/src/interfaces/cli/routes/index.js +2 -0
- package/src/interfaces/cli/routes/log.js +1 -1
- package/src/interfaces/cli/routes/memory.js +3 -2
- package/src/interfaces/cli/routes/panel.js +15 -2
- package/src/interfaces/cli/routes/profile.js +3 -2
- package/src/interfaces/cli/routes/transcribe.js +10 -0
- package/src/interfaces/cli/stdin.js +29 -0
- package/src/interfaces/desktop/assets/blobs/amatista.png +0 -0
- package/src/interfaces/desktop/assets/blobs/aqua.png +0 -0
- package/src/interfaces/desktop/assets/blobs/brasa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/campana.png +0 -0
- package/src/interfaces/desktop/assets/blobs/caracol.png +0 -0
- package/src/interfaces/desktop/assets/blobs/carbon.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cobalto.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cometa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/coral.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cubi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/eclipse.png +0 -0
- package/src/interfaces/desktop/assets/blobs/faro.png +0 -0
- package/src/interfaces/desktop/assets/blobs/gajo.png +0 -0
- package/src/interfaces/desktop/assets/blobs/iris.png +0 -0
- package/src/interfaces/desktop/assets/blobs/kiwi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/laguna.png +0 -0
- package/src/interfaces/desktop/assets/blobs/lila.png +0 -0
- package/src/interfaces/desktop/assets/blobs/menta.png +0 -0
- package/src/interfaces/desktop/assets/blobs/nimbo.png +0 -0
- package/src/interfaces/desktop/assets/blobs/noche.png +0 -0
- package/src/interfaces/desktop/assets/blobs/onyx.png +0 -0
- package/src/interfaces/desktop/assets/blobs/orbita.png +0 -0
- package/src/interfaces/desktop/assets/blobs/ovni.png +0 -0
- package/src/interfaces/desktop/assets/blobs/papa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/parche.png +0 -0
- package/src/interfaces/desktop/assets/blobs/peon.png +0 -0
- package/src/interfaces/desktop/assets/blobs/perla.png +0 -0
- package/src/interfaces/desktop/assets/blobs/pino.png +0 -0
- package/src/interfaces/desktop/assets/blobs/quad.png +0 -0
- package/src/interfaces/desktop/assets/blobs/rubi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/saturno.png +0 -0
- package/src/interfaces/desktop/assets/blobs/trebol.png +0 -0
- package/src/interfaces/desktop/assets/blobs/trino.png +0 -0
- package/src/interfaces/desktop/assets/blobs/volcan.png +0 -0
- package/src/interfaces/desktop/assets/blobs/zafiro.png +0 -0
- package/src/interfaces/desktop/assets/notification.mp3 +0 -0
- package/src/interfaces/desktop/main.js +473 -29
- package/src/interfaces/desktop/mascot-blobs.js +41 -0
- package/src/interfaces/desktop/mascot-preload.js +32 -0
- package/src/interfaces/desktop/mascot.css +186 -0
- package/src/interfaces/desktop/mascot.html +40 -0
- package/src/interfaces/desktop/mascot.js +163 -0
- package/src/interfaces/desktop/preload.js +10 -0
- package/src/interfaces/desktop/renderer.js +308 -48
- package/src/interfaces/desktop/style.css +34 -0
- package/src/interfaces/mcp-server/index.js +87 -0
- package/src/interfaces/tui/_shims/util-locale.ts +0 -2
- package/src/interfaces/tui/app.tsx +0 -6
- package/src/interfaces/tui/attach.ts +0 -1
- package/src/interfaces/tui/context/sdk-apx.tsx +0 -4
- package/src/interfaces/tui/plugin/api.tsx +0 -3
- package/src/interfaces/tui/plugin/runtime.ts +0 -3
- package/src/interfaces/tui/thread.ts +0 -16
- package/src/interfaces/web/README.md +22 -14
- package/src/interfaces/web/dist/assets/claude-XtpLmGtF.webp +0 -0
- package/src/interfaces/web/dist/assets/codex-DExPUgvh.webp +0 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css +32 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.br +0 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.gz +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js +1074 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.br +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.gz +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map +1 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.br +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.gz +0 -0
- package/src/interfaces/web/dist/favicon/dark/site.webmanifest +12 -6
- package/src/interfaces/web/dist/favicon/white/site.webmanifest +12 -6
- package/src/interfaces/web/dist/index.html +22 -6
- package/src/interfaces/web/dist/index.html.br +0 -0
- package/src/interfaces/web/dist/index.html.gz +0 -0
- package/src/interfaces/web/dist/manifest.webmanifest +25 -0
- package/src/interfaces/web/dist/modules/blobs/amatista.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/aqua.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/brasa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/campana.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/caracol.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/carbon.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cobalto.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cometa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/coral.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cubi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/eclipse.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/faro.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/gajo.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/iris.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/kiwi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/laguna.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/lila.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/menta.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/nimbo.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/noche.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/onyx.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/orbita.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/ovni.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/papa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/parche.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/peon.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/perla.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/pino.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/quad.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/rubi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/saturno.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/trebol.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/trino.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/volcan.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/zafiro.png +0 -0
- package/src/interfaces/web/dist/sw.js +106 -0
- package/src/interfaces/web/dist/sw.js.br +0 -0
- package/src/interfaces/web/dist/sw.js.gz +0 -0
- package/src/interfaces/web/eslint.config.js +83 -0
- package/src/interfaces/web/index.html +20 -4
- package/src/interfaces/web/package-lock.json +1651 -1280
- package/src/interfaces/web/package.json +9 -10
- package/src/interfaces/web/pnpm-lock.yaml +867 -869
- package/src/interfaces/web/public/favicon/dark/site.webmanifest +12 -6
- package/src/interfaces/web/public/favicon/white/site.webmanifest +12 -6
- package/src/interfaces/web/public/manifest.webmanifest +25 -0
- package/src/interfaces/web/public/modules/blobs/amatista.png +0 -0
- package/src/interfaces/web/public/modules/blobs/aqua.png +0 -0
- package/src/interfaces/web/public/modules/blobs/brasa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/campana.png +0 -0
- package/src/interfaces/web/public/modules/blobs/caracol.png +0 -0
- package/src/interfaces/web/public/modules/blobs/carbon.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cobalto.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cometa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/coral.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cubi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/eclipse.png +0 -0
- package/src/interfaces/web/public/modules/blobs/faro.png +0 -0
- package/src/interfaces/web/public/modules/blobs/gajo.png +0 -0
- package/src/interfaces/web/public/modules/blobs/iris.png +0 -0
- package/src/interfaces/web/public/modules/blobs/kiwi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/laguna.png +0 -0
- package/src/interfaces/web/public/modules/blobs/lila.png +0 -0
- package/src/interfaces/web/public/modules/blobs/menta.png +0 -0
- package/src/interfaces/web/public/modules/blobs/nimbo.png +0 -0
- package/src/interfaces/web/public/modules/blobs/noche.png +0 -0
- package/src/interfaces/web/public/modules/blobs/onyx.png +0 -0
- package/src/interfaces/web/public/modules/blobs/orbita.png +0 -0
- package/src/interfaces/web/public/modules/blobs/ovni.png +0 -0
- package/src/interfaces/web/public/modules/blobs/papa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/parche.png +0 -0
- package/src/interfaces/web/public/modules/blobs/peon.png +0 -0
- package/src/interfaces/web/public/modules/blobs/perla.png +0 -0
- package/src/interfaces/web/public/modules/blobs/pino.png +0 -0
- package/src/interfaces/web/public/modules/blobs/quad.png +0 -0
- package/src/interfaces/web/public/modules/blobs/rubi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/saturno.png +0 -0
- package/src/interfaces/web/public/modules/blobs/trebol.png +0 -0
- package/src/interfaces/web/public/modules/blobs/trino.png +0 -0
- package/src/interfaces/web/public/modules/blobs/volcan.png +0 -0
- package/src/interfaces/web/public/modules/blobs/zafiro.png +0 -0
- package/src/interfaces/web/public/sw.js +106 -0
- package/src/interfaces/web/src/App.tsx +106 -10
- package/src/interfaces/web/src/assets/cli/claude.webp +0 -0
- package/src/interfaces/web/src/assets/cli/codex.webp +0 -0
- package/src/interfaces/web/src/assets/cli/cursor.svg +1 -0
- package/src/interfaces/web/src/assets/cli/opencode.png +0 -0
- package/src/interfaces/web/src/components/Combobox.tsx +201 -0
- package/src/interfaces/web/src/components/MobileHint.tsx +95 -0
- package/src/interfaces/web/src/components/MobileLinkDialog.tsx +156 -0
- package/src/interfaces/web/src/components/ModelCombobox.tsx +21 -113
- package/src/interfaces/web/src/components/{routines/ReadOnlyBlock.tsx → ReadOnlyBlock.tsx} +13 -4
- package/src/interfaces/web/src/components/Roby.tsx +5 -3
- package/src/interfaces/web/src/components/RobyBubble.tsx +23 -5
- package/src/interfaces/web/src/components/RowMenu.tsx +46 -0
- package/src/interfaces/web/src/components/TimezoneSelect.tsx +4 -1
- package/src/interfaces/web/src/components/Toast.tsx +50 -14
- package/src/interfaces/web/src/components/UiSelect.tsx +12 -5
- package/src/interfaces/web/src/components/agents/AgentAvatar.tsx +171 -0
- package/src/interfaces/web/src/components/agents/AgentFormFields.tsx +42 -11
- package/src/interfaces/web/src/components/agents/AgentModelBadge.tsx +157 -0
- package/src/interfaces/web/src/components/agents/AgentModelSelect.tsx +57 -0
- package/src/interfaces/web/src/components/agents/AgentSkillsPicker.tsx +115 -0
- package/src/interfaces/web/src/components/agents/BlobAvatar.tsx +50 -0
- package/src/interfaces/web/src/components/agents/blobPresets.ts +50 -0
- package/src/interfaces/web/src/components/agents/modelCatalog.ts +66 -0
- package/src/interfaces/web/src/components/chat/ActionGroup.tsx +162 -0
- package/src/interfaces/web/src/components/chat/AskAnswersCard.tsx +4 -3
- package/src/interfaces/web/src/components/chat/AskQuestionsCard.tsx +1 -1
- package/src/interfaces/web/src/components/chat/Attachment.tsx +220 -0
- package/src/interfaces/web/src/components/chat/ChatList.tsx +226 -51
- package/src/interfaces/web/src/components/chat/ChatRowActivity.tsx +45 -0
- package/src/interfaces/web/src/components/chat/Composer.tsx +672 -23
- package/src/interfaces/web/src/components/chat/ComposerCommands.tsx +175 -0
- package/src/interfaces/web/src/components/chat/ComposerSuggest.tsx +215 -0
- package/src/interfaces/web/src/components/chat/ContextBar.tsx +133 -65
- package/src/interfaces/web/src/components/chat/InlineAskPanel.tsx +107 -47
- package/src/interfaces/web/src/components/chat/MessageBubble.tsx +460 -119
- package/src/interfaces/web/src/components/chat/MessageList.tsx +165 -18
- package/src/interfaces/web/src/components/chat/ReasoningBlock.tsx +58 -0
- package/src/interfaces/web/src/components/chat/SessionPicker.tsx +182 -0
- package/src/interfaces/web/src/components/chat/SkillTrace.tsx +183 -0
- package/src/interfaces/web/src/components/chat/ToolCall.tsx +11 -11
- package/src/interfaces/web/src/components/code/CodeContextTab.tsx +87 -53
- package/src/interfaces/web/src/components/code/CodeFileTree.tsx +11 -52
- package/src/interfaces/web/src/components/code/CodeFileViewer.tsx +5 -4
- package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +31 -7
- package/src/interfaces/web/src/components/code/CodeSessionList.tsx +32 -11
- package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +33 -3
- package/src/interfaces/web/src/components/code/CodeTerminal.tsx +5 -4
- package/src/interfaces/web/src/components/code/NewCodeSessionDialog.tsx +164 -0
- package/src/interfaces/web/src/components/commitments/CommitmentDetail.tsx +162 -0
- package/src/interfaces/web/src/components/commitments/CommitmentFormDialog.tsx +158 -0
- package/src/interfaces/web/src/components/commitments/CommitmentList.tsx +194 -0
- package/src/interfaces/web/src/components/commitments/commitmentState.tsx +46 -0
- package/src/interfaces/web/src/components/common/BulkActionBar.tsx +60 -0
- package/src/interfaces/web/src/components/common/ConfirmDialog.tsx +4 -1
- package/src/interfaces/web/src/components/common/SelectCheckbox.tsx +40 -0
- package/src/interfaces/web/src/components/common/TabNav.tsx +1 -1
- package/src/interfaces/web/src/components/cron/CronPicker.tsx +1 -1
- package/src/interfaces/web/src/components/files/FileBrowser.tsx +1 -1
- package/src/interfaces/web/src/components/files/FileTree.tsx +6 -4
- package/src/interfaces/web/src/components/files/FileViewer.tsx +9 -5
- package/src/interfaces/web/src/components/files/MarkdownPreview.tsx +45 -9
- package/src/interfaces/web/src/components/images/ImageDefaultsCard.tsx +93 -0
- package/src/interfaces/web/src/components/images/ImageProviderList.tsx +142 -0
- package/src/interfaces/web/src/components/images/ImageProviderModal.tsx +263 -0
- package/src/interfaces/web/src/components/images/ImageTestCard.tsx +142 -0
- package/src/interfaces/web/src/components/inbox/ChannelFilter.tsx +178 -0
- package/src/interfaces/web/src/components/inbox/InboxList.tsx +77 -81
- package/src/interfaces/web/src/components/inbox/InboxRowItem.tsx +140 -0
- package/src/interfaces/web/src/components/integrations/ComingSoonPlugin.tsx +2 -2
- package/src/interfaces/web/src/components/integrations/PluginConnect.tsx +208 -30
- package/src/interfaces/web/src/components/integrations/PluginToolsSection.tsx +1 -1
- package/src/interfaces/web/src/components/layout/ProjectAvatar.tsx +39 -24
- package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +253 -58
- package/src/interfaces/web/src/components/memory/MemoryBrowser.tsx +94 -47
- package/src/interfaces/web/src/components/routines/ExecutionsList.tsx +202 -90
- package/src/interfaces/web/src/components/routines/RoutineDetail.tsx +28 -6
- package/src/interfaces/web/src/components/routines/RoutineEditor.tsx +16 -5
- package/src/interfaces/web/src/components/routines/RoutineList.tsx +49 -9
- package/src/interfaces/web/src/components/routines/VarTextarea.tsx +1 -1
- package/src/interfaces/web/src/components/routines/runChat.ts +121 -0
- package/src/interfaces/web/src/components/sessions/SessionDetail.tsx +148 -0
- package/src/interfaces/web/src/components/sessions/SessionTerminal.tsx +98 -0
- package/src/interfaces/web/src/components/settings/AccessPanel.tsx +205 -0
- package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +246 -101
- package/src/interfaces/web/src/components/settings/DesktopSettingsPanel.tsx +36 -2
- package/src/interfaces/web/src/components/settings/DevicesPanel.tsx +19 -6
- package/src/interfaces/web/src/components/settings/EmbedProviderList.tsx +274 -0
- package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +26 -6
- package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +118 -119
- package/src/interfaces/web/src/components/settings/NudgePanel.tsx +4 -3
- package/src/interfaces/web/src/components/settings/PairDeviceDialog.tsx +15 -4
- package/src/interfaces/web/src/components/settings/PanelPrefs.tsx +374 -0
- package/src/interfaces/web/src/components/settings/ProfilePanel.tsx +70 -2
- package/src/interfaces/web/src/components/settings/RoutingPanel.tsx +2 -1
- package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +102 -43
- package/src/interfaces/web/src/components/settings/SkillsManager.tsx +76 -21
- package/src/interfaces/web/src/components/settings/SkillsSettings.tsx +10 -3
- package/src/interfaces/web/src/components/settings/SuperAgentPanel.tsx +8 -0
- package/src/interfaces/web/src/components/settings/TelegramChannelsPanel.tsx +11 -2
- package/src/interfaces/web/src/components/settings/TelegramContactsPanel.tsx +19 -8
- package/src/interfaces/web/src/components/settings/TelegramRolesPanel.tsx +12 -2
- package/src/interfaces/web/src/components/settings/WebPanel.tsx +22 -31
- package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +15 -3
- package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +97 -66
- package/src/interfaces/web/src/components/settings/providers/ProviderTestDialog.tsx +150 -0
- package/src/interfaces/web/src/components/settings/providers/typeStyles.ts +67 -25
- package/src/interfaces/web/src/components/settings/providers/types.ts +3 -0
- package/src/interfaces/web/src/components/tasks/TaskBoard.tsx +201 -0
- package/src/interfaces/web/src/components/tasks/TaskColumnsDialog.tsx +243 -0
- package/src/interfaces/web/src/components/tasks/TaskComments.tsx +167 -0
- package/src/interfaces/web/src/components/tasks/TaskDetail.tsx +335 -0
- package/src/interfaces/web/src/components/tasks/TaskFormDialog.tsx +406 -0
- package/src/interfaces/web/src/components/tasks/TaskList.tsx +258 -0
- package/src/interfaces/web/src/components/tasks/TaskSubtasks.tsx +126 -0
- package/src/interfaces/web/src/components/tasks/columns.ts +51 -0
- package/src/interfaces/web/src/components/tasks/taskStatus.tsx +159 -34
- package/src/interfaces/web/src/components/tasks/taskViewPrefs.ts +73 -0
- package/src/interfaces/web/src/components/tasks/useTaskColumns.ts +31 -0
- package/src/interfaces/web/src/components/ui/chat-input.tsx +136 -12
- package/src/interfaces/web/src/components/ui/context-menu.tsx +15 -198
- package/src/interfaces/web/src/components/ui/dialog.tsx +3 -2
- package/src/interfaces/web/src/components/ui/filter-chips.tsx +4 -0
- package/src/interfaces/web/src/components/ui/popover.tsx +14 -49
- package/src/interfaces/web/src/components/ui/sheet.tsx +2 -1
- package/src/interfaces/web/src/components/ui/spinner.tsx +2 -1
- package/src/interfaces/web/src/components/ui.tsx +62 -23
- package/src/interfaces/web/src/components/voice/VoiceProviderList.tsx +2 -1
- package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +66 -8
- package/src/interfaces/web/src/components/voice/VoiceQvoxInstallCard.tsx +63 -0
- package/src/interfaces/web/src/components/voice/VoiceQvoxStatusCard.tsx +51 -0
- package/src/interfaces/web/src/components/voice/VoiceSttCard.tsx +4 -3
- package/src/interfaces/web/src/components/voice/VoiceTestCard.tsx +38 -4
- package/src/interfaces/web/src/constants/index.ts +1 -0
- package/src/interfaces/web/src/hooks/useChannelPrefs.ts +39 -0
- package/src/interfaces/web/src/hooks/useChat.ts +1092 -85
- package/src/interfaces/web/src/hooks/useChatActivity.ts +24 -0
- package/src/interfaces/web/src/hooks/useInbox.ts +26 -4
- package/src/interfaces/web/src/hooks/useLiveMessages.ts +16 -0
- package/src/interfaces/web/src/hooks/useOllamaModels.ts +79 -0
- package/src/interfaces/web/src/hooks/useRecorder.ts +198 -0
- package/src/interfaces/web/src/hooks/useTokenBootstrap.ts +23 -6
- package/src/interfaces/web/src/i18n/en.ts +832 -175
- package/src/interfaces/web/src/i18n/es.ts +841 -188
- package/src/interfaces/web/src/lib/api/agents.ts +23 -4
- package/src/interfaces/web/src/lib/api/code.ts +17 -0
- package/src/interfaces/web/src/lib/api/commitments.ts +7 -1
- package/src/interfaces/web/src/lib/api/conversations.ts +38 -11
- package/src/interfaces/web/src/lib/api/embeddings.ts +3 -0
- package/src/interfaces/web/src/lib/api/engines.ts +14 -0
- package/src/interfaces/web/src/lib/api/groups.ts +93 -0
- package/src/interfaces/web/src/lib/api/images.ts +193 -0
- package/src/interfaces/web/src/lib/api/inbox.ts +29 -5
- package/src/interfaces/web/src/lib/api/integrations.ts +9 -0
- package/src/interfaces/web/src/lib/api/media.ts +126 -0
- package/src/interfaces/web/src/lib/api/net.ts +44 -0
- package/src/interfaces/web/src/lib/api/profiles.ts +12 -0
- package/src/interfaces/web/src/lib/api/projects.ts +9 -1
- package/src/interfaces/web/src/lib/api/routines.ts +9 -1
- package/src/interfaces/web/src/lib/api/sessions.ts +18 -0
- package/src/interfaces/web/src/lib/api/skills.ts +8 -0
- package/src/interfaces/web/src/lib/api/super_agent.ts +3 -0
- package/src/interfaces/web/src/lib/api/tasks.ts +46 -6
- package/src/interfaces/web/src/lib/api/tools.ts +2 -0
- package/src/interfaces/web/src/lib/api/transcribe.ts +31 -0
- package/src/interfaces/web/src/lib/api/turns.ts +20 -0
- package/src/interfaces/web/src/lib/api/voice.ts +72 -2
- package/src/interfaces/web/src/lib/api.ts +3 -0
- package/src/interfaces/web/src/lib/channels.ts +214 -0
- package/src/interfaces/web/src/lib/chat-activity.ts +175 -0
- package/src/interfaces/web/src/lib/chat-prefs.ts +48 -0
- package/src/interfaces/web/src/lib/code-context.ts +0 -2
- package/src/interfaces/web/src/lib/http.ts +51 -17
- package/src/interfaces/web/src/lib/inbox-selection.ts +29 -0
- package/src/interfaces/web/src/lib/live.ts +252 -0
- package/src/interfaces/web/src/lib/net.ts +211 -0
- package/src/interfaces/web/src/lib/notify.ts +331 -0
- package/src/interfaces/web/src/lib/projectNav.ts +40 -0
- package/src/interfaces/web/src/lib/pwa.ts +115 -0
- package/src/interfaces/web/src/lib/qvox.ts +24 -0
- package/src/interfaces/web/src/lib/slug.ts +3 -0
- package/src/interfaces/web/src/lib/tone.ts +150 -0
- package/src/interfaces/web/src/main.tsx +15 -4
- package/src/interfaces/web/src/screens/ApxAdminScreen.tsx +33 -11
- package/src/interfaces/web/src/screens/InboxScreen.tsx +126 -71
- package/src/interfaces/web/src/screens/ProjectScreen.tsx +8 -4
- package/src/interfaces/web/src/screens/SettingsScreen.tsx +7 -4
- package/src/interfaces/web/src/screens/base/AgentDefaultsTab.tsx +30 -9
- package/src/interfaces/web/src/screens/base/CommitmentsTab.tsx +150 -168
- package/src/interfaces/web/src/screens/base/LogsTab.tsx +8 -7
- package/src/interfaces/web/src/screens/base/SessionsTab.tsx +99 -37
- package/src/interfaces/web/src/screens/base/WorkspacesTab.tsx +1 -1
- package/src/interfaces/web/src/screens/mobile/MobileChat.tsx +85 -0
- package/src/interfaces/web/src/screens/mobile/MobileChatList.tsx +244 -0
- package/src/interfaces/web/src/screens/mobile/MobileCommitments.tsx +350 -0
- package/src/interfaces/web/src/screens/mobile/MobileScreen.tsx +138 -0
- package/src/interfaces/web/src/screens/mobile/MobileTabBar.tsx +105 -0
- package/src/interfaces/web/src/screens/mobile/MobileTasks.tsx +407 -0
- package/src/interfaces/web/src/screens/mobile/NewChatSheet.tsx +313 -0
- package/src/interfaces/web/src/screens/mobile/mobileList.tsx +194 -0
- package/src/interfaces/web/src/screens/mobile/routes.ts +239 -0
- package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +135 -64
- package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +0 -1
- package/src/interfaces/web/src/screens/modules/ImagesScreen.tsx +172 -0
- package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +36 -4
- package/src/interfaces/web/src/screens/project/AgentBrainGraph.tsx +117 -30
- package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +537 -92
- package/src/interfaces/web/src/screens/project/AgentsTab.tsx +344 -93
- package/src/interfaces/web/src/screens/project/ArtifactsTab.tsx +1 -1
- package/src/interfaces/web/src/screens/project/ChatTab.tsx +1160 -94
- package/src/interfaces/web/src/screens/project/IntegrationsTab.tsx +3 -2
- package/src/interfaces/web/src/screens/project/McpsTab.tsx +62 -14
- package/src/interfaces/web/src/screens/project/Overview.tsx +36 -15
- package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +93 -8
- package/src/interfaces/web/src/screens/project/SkillsTab.tsx +4 -1
- package/src/interfaces/web/src/screens/project/StructureTab.tsx +5 -4
- package/src/interfaces/web/src/screens/project/TasksTab.tsx +351 -129
- package/src/interfaces/web/src/screens/project/VarsTab.tsx +17 -5
- package/src/interfaces/web/src/styles.css +106 -31
- package/src/interfaces/web/src/types/daemon.ts +246 -2
- package/src/interfaces/web/src/vite-env.d.ts +20 -0
- package/src/interfaces/tui/plugin/command-shim.ts +0 -109
- package/src/interfaces/web/components.json +0 -25
- package/src/interfaces/web/dist/assets/index-CvEoGtTf.js +0 -849
- package/src/interfaces/web/dist/assets/index-CvEoGtTf.js.map +0 -1
- package/src/interfaces/web/dist/assets/index-DzBBXFaO.css +0 -1
- package/src/interfaces/web/src/components/tasks/TaskDetailPanel.tsx +0 -142
- package/src/interfaces/web/src/components/ui/accordion.tsx +0 -72
- package/src/interfaces/web/src/components/ui/alert-dialog.tsx +0 -187
- package/src/interfaces/web/src/components/ui/alert.tsx +0 -76
- package/src/interfaces/web/src/components/ui/aspect-ratio.tsx +0 -22
- package/src/interfaces/web/src/components/ui/avatar.tsx +0 -107
- package/src/interfaces/web/src/components/ui/breadcrumb.tsx +0 -125
- package/src/interfaces/web/src/components/ui/button-group.tsx +0 -87
- package/src/interfaces/web/src/components/ui/calendar.tsx +0 -221
- package/src/interfaces/web/src/components/ui/card.tsx +0 -103
- package/src/interfaces/web/src/components/ui/carousel.tsx +0 -242
- package/src/interfaces/web/src/components/ui/chart.tsx +0 -371
- package/src/interfaces/web/src/components/ui/checkbox.tsx +0 -29
- package/src/interfaces/web/src/components/ui/collapsible.tsx +0 -19
- package/src/interfaces/web/src/components/ui/combobox.tsx +0 -295
- package/src/interfaces/web/src/components/ui/command.tsx +0 -196
- package/src/interfaces/web/src/components/ui/direction.tsx +0 -4
- package/src/interfaces/web/src/components/ui/drawer.tsx +0 -134
- package/src/interfaces/web/src/components/ui/empty.tsx +0 -104
- package/src/interfaces/web/src/components/ui/field.tsx +0 -236
- package/src/interfaces/web/src/components/ui/hover-card.tsx +0 -51
- package/src/interfaces/web/src/components/ui/input-otp.tsx +0 -85
- package/src/interfaces/web/src/components/ui/item.tsx +0 -201
- package/src/interfaces/web/src/components/ui/menubar.tsx +0 -280
- package/src/interfaces/web/src/components/ui/native-select.tsx +0 -61
- package/src/interfaces/web/src/components/ui/navigation-menu.tsx +0 -168
- package/src/interfaces/web/src/components/ui/pagination.tsx +0 -130
- package/src/interfaces/web/src/components/ui/progress.tsx +0 -83
- package/src/interfaces/web/src/components/ui/radio-group.tsx +0 -36
- package/src/interfaces/web/src/components/ui/resizable.tsx +0 -50
- package/src/interfaces/web/src/components/ui/scroll-area.tsx +0 -53
- package/src/interfaces/web/src/components/ui/sidebar.tsx +0 -726
- package/src/interfaces/web/src/components/ui/slider.tsx +0 -52
- package/src/interfaces/web/src/components/ui/sonner.tsx +0 -49
- package/src/interfaces/web/src/components/ui/table.tsx +0 -116
- package/src/interfaces/web/src/components/ui/toggle-group.tsx +0 -87
- package/src/interfaces/web/src/components/ui/toggle.tsx +0 -45
- package/src/interfaces/web/src/hooks/use-mobile.ts +0 -19
- package/src/interfaces/web/src/screens/base/GlobalTasksTab.tsx +0 -161
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
// One turn of a project agent — THE shared turn engine, used by the 1:1 chat
|
|
2
|
+
// route (host/daemon/api/exec.js), the group cascade (agent/group), and anyone
|
|
3
|
+
// else who needs an agent to answer with its real tools.
|
|
4
|
+
//
|
|
5
|
+
// WHY THIS EXISTS (moved here from exec.js so it can be reused without a route
|
|
6
|
+
// importing from another route). This used to be `callEngine` and nothing else:
|
|
7
|
+
// system prompt in, text out, no tools anywhere — which is why an agent asked to
|
|
8
|
+
// browse answered with a fenced {"tool":"browser_navigate",…} instead of
|
|
9
|
+
// browsing. It had nothing to call, so narrating the call was the only move left
|
|
10
|
+
// to it. Now the same loop the routine runner uses runs here too, gated by the
|
|
11
|
+
// same `resolveAgentAllowedTools` — the agent's declared `tools:` field when it
|
|
12
|
+
// has one, the broad default when it does not.
|
|
13
|
+
//
|
|
14
|
+
// `tools: false` keeps the old shape for a caller that wants one model call and
|
|
15
|
+
// no side effects.
|
|
16
|
+
import { callEngine } from "#core/engines/index.js";
|
|
17
|
+
import { resolveAgentAllowedTools } from "#core/agent/agent-tools.js";
|
|
18
|
+
import { runAgent } from "#core/agent/index.js";
|
|
19
|
+
import { createToolSession, makeToolHandlers } from "#core/agent/tools/registry.js";
|
|
20
|
+
import { loadAgentSkills, collectAgentSkillMedia } from "#core/agent/skills/agent-skills.js";
|
|
21
|
+
import { scopeProjects } from "#core/apc/projects-helpers.js";
|
|
22
|
+
import { channelToolIters, MAX_TOOL_ITERS } from "#core/agent/constants.js";
|
|
23
|
+
import { judgeConfig, judgeCompletion, applyJudgeLoop, continuableTurn } from "#core/agent/judge.js";
|
|
24
|
+
|
|
25
|
+
// A chat reply is prose, not a Telegram one-liner: run-agent's 512-token default
|
|
26
|
+
// truncates an agent mid-answer on the surface where the whole answer is the
|
|
27
|
+
// point. Same headroom the routine runner gives itself.
|
|
28
|
+
export const AGENT_TURN_MAX_TOKENS = 4096;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @returns {{text, trace, usage, model, allowedTools, media, endedAwaitingUser, judge?}}
|
|
32
|
+
* `media` is what the agent attached to THIS reply (attach_media). The caller
|
|
33
|
+
* delivers it and records it on the turn; an empty array means it sent none.
|
|
34
|
+
* `endedAwaitingUser` is true when the turn closed by asking the user
|
|
35
|
+
* something, so nobody answers on their behalf. `judge` is the verdict trail,
|
|
36
|
+
* present only when the completion judge actually scored the turn.
|
|
37
|
+
*/
|
|
38
|
+
export async function runAgentTurn({
|
|
39
|
+
p,
|
|
40
|
+
agent,
|
|
41
|
+
modelId,
|
|
42
|
+
system,
|
|
43
|
+
prompt,
|
|
44
|
+
previousMessages = [],
|
|
45
|
+
// Images that arrived with this turn: [{ kind, mime, data, path }]. Only the
|
|
46
|
+
// tool-driven path forwards them — the toolless callEngine branch is text.
|
|
47
|
+
attachments = [],
|
|
48
|
+
channel,
|
|
49
|
+
channelMeta,
|
|
50
|
+
temperature,
|
|
51
|
+
maxTokens,
|
|
52
|
+
tools = true,
|
|
53
|
+
// Left unset, the channel decides (channelToolIters). A project agent in the
|
|
54
|
+
// web chat is on the same watched surface Roby is, and was stopping every 9
|
|
55
|
+
// actions to ask whether to continue — the budget belongs to the surface, not
|
|
56
|
+
// to which agent happens to be answering.
|
|
57
|
+
maxIters,
|
|
58
|
+
projects,
|
|
59
|
+
plugins,
|
|
60
|
+
registries,
|
|
61
|
+
config,
|
|
62
|
+
onEvent = null,
|
|
63
|
+
onToken = null,
|
|
64
|
+
requestConfirmation = null,
|
|
65
|
+
// Cancellation. Without it a turn could only be stopped by not looking at it:
|
|
66
|
+
// the caller's stream closing does not end the run (that is what lets another
|
|
67
|
+
// tab catch up), so "stop" and "interrupt" both come down to signalling this.
|
|
68
|
+
signal = null,
|
|
69
|
+
// The completion judge, injectable so a test can supply verdicts without an
|
|
70
|
+
// engine. Production always uses the real one.
|
|
71
|
+
judgeCompletionFn = judgeCompletion,
|
|
72
|
+
}) {
|
|
73
|
+
const cap = Number.isFinite(Number(maxTokens)) ? Number(maxTokens) : AGENT_TURN_MAX_TOKENS;
|
|
74
|
+
|
|
75
|
+
if (tools === false) {
|
|
76
|
+
const result = await callEngine({
|
|
77
|
+
modelId,
|
|
78
|
+
system,
|
|
79
|
+
messages: [...previousMessages, { role: "user", content: prompt }],
|
|
80
|
+
config: p.config || config,
|
|
81
|
+
temperature,
|
|
82
|
+
maxTokens,
|
|
83
|
+
signal,
|
|
84
|
+
});
|
|
85
|
+
return {
|
|
86
|
+
text: result.text || "",
|
|
87
|
+
trace: [],
|
|
88
|
+
usage: result.usage,
|
|
89
|
+
// What ANSWERED, which is not always what was resolved: routing can fall
|
|
90
|
+
// back mid-turn, and the caller should be told which model replied.
|
|
91
|
+
model: result.model || modelId,
|
|
92
|
+
allowedTools: [],
|
|
93
|
+
media: [],
|
|
94
|
+
// One model call, no tools, no loop: there is nothing here that could
|
|
95
|
+
// have stopped halfway, and nothing that could have asked.
|
|
96
|
+
endedAwaitingUser: false,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const cfg = structuredClone(p.config || config || {});
|
|
101
|
+
// Deliberately NOT forcing permission_mode. A routine pins it to "total"
|
|
102
|
+
// because a scheduled run has nobody to approve a dangerous tool; a chat has
|
|
103
|
+
// a person on the other end, so the configured policy stands and a blocked
|
|
104
|
+
// tool comes back to the model as an observation it can re-plan around.
|
|
105
|
+
const allowedTools = resolveAgentAllowedTools(agent);
|
|
106
|
+
// The allowlist decides WHAT it may call; the channel decides how much of it
|
|
107
|
+
// is loaded up front — a full channel gets the lot, a lightweight one starts
|
|
108
|
+
// on the base set and expands through discover_tools.
|
|
109
|
+
const toolSession = createToolSession(channel, { allowedTools });
|
|
110
|
+
|
|
111
|
+
// Images this agent's skills declare: the pool attach_media / view_media
|
|
112
|
+
// validate an id against, and the sink a queued attachment lands in.
|
|
113
|
+
//
|
|
114
|
+
// These used to be supplied ONLY by the routine runner, so attach_media was
|
|
115
|
+
// dead on every surface with a person on the other end: the same skills whose
|
|
116
|
+
// image manifest build-agent-system.js had just rendered into the prompt were
|
|
117
|
+
// not attachable, and the tool answered "no attachable images — this agent's
|
|
118
|
+
// skills declare none" to a model that could see them listed. A skill's
|
|
119
|
+
// picture is at its most useful mid-conversation, which was the one place it
|
|
120
|
+
// could not be sent.
|
|
121
|
+
const attachableMedia = collectAgentSkillMedia(loadAgentSkills(p, agent));
|
|
122
|
+
const mediaSink = [];
|
|
123
|
+
|
|
124
|
+
// An explicit budget from the caller always wins; otherwise the surface's own
|
|
125
|
+
// default applies. See channelToolIters.
|
|
126
|
+
//
|
|
127
|
+
// Resolved to a NUMBER, falling through to runAgent's own default rather than
|
|
128
|
+
// leaving it unset, because this is the turn's total and the judge loop below
|
|
129
|
+
// subtracts from it. "Whatever runAgent picks" is not a total you can share
|
|
130
|
+
// between rounds. Same resolution runSuperAgent does.
|
|
131
|
+
const turnMaxIters = (Number.isFinite(Number(maxIters)) && Number(maxIters) > 0
|
|
132
|
+
? Number(maxIters)
|
|
133
|
+
: channelToolIters(cfg, channel)) || MAX_TOOL_ITERS;
|
|
134
|
+
|
|
135
|
+
const hasImage = (attachments || []).some((a) => a?.data && /^image\//.test(a.mime || ""));
|
|
136
|
+
// `iters` is what THIS pass may spend: the whole budget for the first run,
|
|
137
|
+
// whatever is left for a judge round.
|
|
138
|
+
const runOnce = (turnPrompt, history, iters = turnMaxIters) =>
|
|
139
|
+
runAgent({
|
|
140
|
+
globalConfig: cfg,
|
|
141
|
+
system,
|
|
142
|
+
prompt: turnPrompt,
|
|
143
|
+
previousMessages: history,
|
|
144
|
+
attachments,
|
|
145
|
+
overrideModel: modelId,
|
|
146
|
+
toolSchemas: toolSession.initialSchemas,
|
|
147
|
+
makeToolHandlers,
|
|
148
|
+
toolHandlerCtx: {
|
|
149
|
+
// Same scoping as a routine run: this agent belongs to `p`, so that is
|
|
150
|
+
// what an unqualified path means to it. See scopeProjects.
|
|
151
|
+
projects: scopeProjects(projects, p.id),
|
|
152
|
+
plugins,
|
|
153
|
+
registries,
|
|
154
|
+
globalConfig: cfg,
|
|
155
|
+
channel,
|
|
156
|
+
channelMeta: {
|
|
157
|
+
...(channelMeta || {}),
|
|
158
|
+
...(hasImage ? { has_image: true } : {}),
|
|
159
|
+
agentSlug: agent.slug,
|
|
160
|
+
projectPath: p.path,
|
|
161
|
+
},
|
|
162
|
+
toolSession,
|
|
163
|
+
attachableMedia,
|
|
164
|
+
mediaSink,
|
|
165
|
+
requestConfirmation,
|
|
166
|
+
},
|
|
167
|
+
agentName: agent.slug,
|
|
168
|
+
maxTokens: cap,
|
|
169
|
+
signal,
|
|
170
|
+
maxIters: iters,
|
|
171
|
+
onEvent,
|
|
172
|
+
onToken,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
let result = await runOnce(prompt, previousMessages);
|
|
176
|
+
|
|
177
|
+
// Goal-completion judge — the same loop runSuperAgent runs, on the same
|
|
178
|
+
// switch (`super_agent.judge.continue_unfinished`, on by default).
|
|
179
|
+
//
|
|
180
|
+
// A conversational turn ends when the model stops calling tools, which is
|
|
181
|
+
// also what it does when it merely ANNOUNCES its next step ("ahora genero el
|
|
182
|
+
// SRT") and writes no call: nothing is finished, nothing was asked, and the
|
|
183
|
+
// task sits there until a person types "seguí". The super-agent has been
|
|
184
|
+
// continued automatically since b071e70; every project agent was still
|
|
185
|
+
// waiting to be poked, so Magui stalled in the web chat where Roby did not.
|
|
186
|
+
//
|
|
187
|
+
// EVERY CHANNEL a project agent answers on, not only the watched ones. The
|
|
188
|
+
// failure is the model's, not the surface's — the announce-instead-of-act
|
|
189
|
+
// turn reads identically on `api` and on `web` — and the two exclusions in
|
|
190
|
+
// continuableTurn already spend the call where it pays: a turn that ran no
|
|
191
|
+
// tools is chat (so "hola" never costs a judge call), and a turn that closed
|
|
192
|
+
// by ASKING is waiting rather than unfinished, which is the regression
|
|
193
|
+
// documented on continuableTurn — continuing it answers over the user's head
|
|
194
|
+
// and re-asks the identical question.
|
|
195
|
+
//
|
|
196
|
+
// Those two make a channel gate redundant, because they already cut per
|
|
197
|
+
// surface for the right reason. A bounded channel (api, and everything else
|
|
198
|
+
// channelToolIters leaves alone) reserves its last iteration for the wrap-up,
|
|
199
|
+
// so a turn that used its whole budget ends by asking and is excluded —
|
|
200
|
+
// leaving only the turn that quit early, which is exactly the bug. The
|
|
201
|
+
// run-to-completion surfaces (web, web_sidebar) have no wrap-up to fall back
|
|
202
|
+
// on, so the judge is the only thing that notices — and there a human is
|
|
203
|
+
// watching the tool calls render, one click from stopping the turn.
|
|
204
|
+
//
|
|
205
|
+
// Cost is one extra model call per JUDGED turn, and after those exclusions
|
|
206
|
+
// the judged population is "ran real tools, then went quiet without asking
|
|
207
|
+
// anything" — where a wasted scoring call is far cheaper than work that
|
|
208
|
+
// stopped halfway and nobody noticed. The group cascade reaches this too: a
|
|
209
|
+
// speaker that ran tools and went quiet is the same bug in a busier room.
|
|
210
|
+
//
|
|
211
|
+
// Not gated on `judge.enabled` — that switch guards the OTHER door, a
|
|
212
|
+
// completion-contract turn's own "done" claim, which project agents never
|
|
213
|
+
// take (no finish tool, no forced tool choice). An aborted turn is the user
|
|
214
|
+
// saying stop, the one instruction a judge must not overrule.
|
|
215
|
+
const jCfg = judgeConfig(cfg);
|
|
216
|
+
if (jCfg.continue_unfinished && !signal?.aborted && continuableTurn(result)) {
|
|
217
|
+
// Rolling refinement history: each round sees the original goal, its own
|
|
218
|
+
// prior reply, and the judge's follow-up as ordinary conversation turns.
|
|
219
|
+
const history = [...previousMessages, { role: "user", content: prompt }];
|
|
220
|
+
result = await applyJudgeLoop({
|
|
221
|
+
initialResult: result,
|
|
222
|
+
cfg: jCfg,
|
|
223
|
+
onEvent,
|
|
224
|
+
// The turn's whole budget, shared with the run above rather than reissued
|
|
225
|
+
// per round. See the "one turn, one budget" note in constants.js.
|
|
226
|
+
maxIters: turnMaxIters,
|
|
227
|
+
// The model that ran the turn is the judge's last-resort scorer: a
|
|
228
|
+
// project agent can be the only agent an install has, and `judge.model` /
|
|
229
|
+
// `super_agent.model` may both be unset.
|
|
230
|
+
judgeFn: (r) => judgeCompletionFn({ goal: prompt, result: r, globalConfig: cfg, fallbackModel: modelId }),
|
|
231
|
+
runFollowup: async (followup, prior, { maxIters: roundIters } = {}) => {
|
|
232
|
+
history.push({ role: "assistant", content: prior.text || "" });
|
|
233
|
+
const next = await runOnce(followup, [...history], roundIters);
|
|
234
|
+
history.push({ role: "user", content: followup });
|
|
235
|
+
return next;
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
text: result.text || "",
|
|
242
|
+
trace: Array.isArray(result.trace) ? result.trace : [],
|
|
243
|
+
usage: result.usage,
|
|
244
|
+
model: result.model || modelId,
|
|
245
|
+
allowedTools,
|
|
246
|
+
// Accumulated across judge rounds by construction: the same sink is handed
|
|
247
|
+
// to every round, so an image attached before the turn was continued still
|
|
248
|
+
// reaches the caller.
|
|
249
|
+
media: mediaSink,
|
|
250
|
+
endedAwaitingUser: !!result.endedAwaitingUser,
|
|
251
|
+
...(result.judge ? { judge: result.judge } : {}),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
@@ -19,8 +19,7 @@ import { SELF_MEMORY_PATH } from "../config/paths.js";
|
|
|
19
19
|
|
|
20
20
|
export { SELF_MEMORY_PATH };
|
|
21
21
|
import { resolveAgentName } from "../identity/index.js";
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
import { appendDatedBullet } from "#core/memory/dated-log.js";
|
|
24
23
|
|
|
25
24
|
function notebookHeader() {
|
|
26
25
|
let name = "";
|
|
@@ -91,59 +90,23 @@ export function readSelfMemoryForPrompt(limit = SELF_MEMORY_PROMPT_LIMIT) {
|
|
|
91
90
|
return out.join("\n").trim();
|
|
92
91
|
}
|
|
93
92
|
|
|
94
|
-
// HH:MM (UTC) for the current time — used to tag notes per the cross-channel
|
|
95
|
-
// format "[HH:MM][canal] nota".
|
|
96
|
-
function nowHm() {
|
|
97
|
-
return new Date().toISOString().slice(11, 16);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
93
|
/**
|
|
101
|
-
* Append a dated note to the notebook.
|
|
102
|
-
* `## YYYY-MM-DD` heading
|
|
103
|
-
* the
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* the cross-channel broker (and the RAG indexer) can attribute the note to a
|
|
107
|
-
* surface and time. Without it the legacy "- note" form is kept.
|
|
94
|
+
* Append a dated note to the notebook. Creates the file (and ~/.apx) on first
|
|
95
|
+
* write. The bullet format — one `## YYYY-MM-DD` heading per day, an
|
|
96
|
+
* "[HH:MM][channel]" tag so the cross-channel broker and the RAG indexer can
|
|
97
|
+
* attribute a note to a surface and a time — lives in core/memory/dated-log.js,
|
|
98
|
+
* shared with project memory and routine memory.
|
|
108
99
|
*/
|
|
109
100
|
export function appendSelfMemory(note, opts = {}) {
|
|
110
101
|
const text = String(note || "").trim();
|
|
111
102
|
if (!text) throw new Error("nothing to remember (empty note)");
|
|
112
103
|
fs.mkdirSync(path.dirname(SELF_MEMORY_PATH), { recursive: true });
|
|
113
104
|
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const tag = channel ? `[${opts.time || nowHm()}][${channel}] ` : "";
|
|
120
|
-
const bullet = `- ${tag}${oneLine}`;
|
|
121
|
-
|
|
122
|
-
let next;
|
|
123
|
-
if (!existing.trim()) {
|
|
124
|
-
next = `${notebookHeader()}\n\n${heading}\n${bullet}\n`;
|
|
125
|
-
} else if (existing.includes(heading)) {
|
|
126
|
-
// Append the bullet under today's existing heading.
|
|
127
|
-
const lines = existing.split("\n");
|
|
128
|
-
const idx = lines.lastIndexOf(heading);
|
|
129
|
-
// Find the end of today's block (next heading or EOF).
|
|
130
|
-
let insertAt = lines.length;
|
|
131
|
-
for (let i = idx + 1; i < lines.length; i++) {
|
|
132
|
-
if (lines[i].startsWith("## ")) {
|
|
133
|
-
insertAt = i;
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
// Trim trailing blank lines inside the block before inserting.
|
|
138
|
-
while (insertAt > idx + 1 && lines[insertAt - 1].trim() === "") insertAt--;
|
|
139
|
-
lines.splice(insertAt, 0, bullet);
|
|
140
|
-
next = lines.join("\n");
|
|
141
|
-
if (!next.endsWith("\n")) next += "\n";
|
|
142
|
-
} else {
|
|
143
|
-
const sep = existing.endsWith("\n") ? "" : "\n";
|
|
144
|
-
next = `${existing}${sep}\n${heading}\n${bullet}\n`;
|
|
145
|
-
}
|
|
146
|
-
|
|
105
|
+
const next = appendDatedBullet(readSelfMemory(), text, {
|
|
106
|
+
channel: opts.channel,
|
|
107
|
+
time: opts.time,
|
|
108
|
+
header: notebookHeader(),
|
|
109
|
+
});
|
|
147
110
|
fs.writeFileSync(SELF_MEMORY_PATH, next);
|
|
148
111
|
return { path: SELF_MEMORY_PATH, note: text };
|
|
149
112
|
}
|
|
@@ -164,12 +127,15 @@ export function ensureSelfMemoryFile() {
|
|
|
164
127
|
// Parse the notebook into structured entries, oldest first. Tolerant of both
|
|
165
128
|
// the legacy "- note" bullets and the tagged "[HH:MM][channel] note" /
|
|
166
129
|
// "[YYYY-MM-DD HH:MM][channel] note" forms. Each entry:
|
|
167
|
-
// { date, time, channel, ts, text }
|
|
130
|
+
// { date, time, channel, ts, text, line }
|
|
131
|
+
// `line` is the 0-based line number in the source text, so a caller editing
|
|
132
|
+
// the file (prune) can remove exactly this bullet and nothing around it.
|
|
168
133
|
export function parseSelfMemoryEntries(text) {
|
|
169
134
|
const out = [];
|
|
170
135
|
let date = "";
|
|
171
|
-
|
|
172
|
-
|
|
136
|
+
const rawLines = String(text || "").split("\n");
|
|
137
|
+
for (let li = 0; li < rawLines.length; li++) {
|
|
138
|
+
const line = rawLines[li].trim();
|
|
173
139
|
const h = line.match(/^##\s+(\d{4}-\d{2}-\d{2})/);
|
|
174
140
|
if (h) {
|
|
175
141
|
date = h[1];
|
|
@@ -203,7 +169,7 @@ export function parseSelfMemoryEntries(text) {
|
|
|
203
169
|
if (!rest) continue;
|
|
204
170
|
const hm = time ? time.padStart(5, "0") : "00:00";
|
|
205
171
|
const ts = date ? `${date}T${hm}:00Z` : "";
|
|
206
|
-
out.push({ date, time, channel: channel || "memory", ts, text: rest });
|
|
172
|
+
out.push({ date, time, channel: channel || "memory", ts, text: rest, line: li });
|
|
207
173
|
}
|
|
208
174
|
return out;
|
|
209
175
|
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// A project agent's DECLARED skills (its `skills:` frontmatter), resolved and
|
|
2
|
+
// rendered for the system prompt — with progressive disclosure.
|
|
3
|
+
//
|
|
4
|
+
// Until now every declared skill was injected whole into the prompt on EVERY
|
|
5
|
+
// run. Cheap for a small skill, wasteful for a big one: a 7 KB syllabus spent
|
|
6
|
+
// ~1.8 K tokens on every heartbeat even though a session teaches one section.
|
|
7
|
+
//
|
|
8
|
+
// The rule here:
|
|
9
|
+
// • small skill (body ≤ EAGER_MAX_CHARS) → inject the full body. One round
|
|
10
|
+
// trip saved is worth more than the tokens; there is nothing to page.
|
|
11
|
+
// • large skill → inject a CARD: description, the
|
|
12
|
+
// section outline, and the image manifest. The agent pulls the one section
|
|
13
|
+
// it needs with read_skill, and attaches/looks at an image with
|
|
14
|
+
// attach_media / view_media. Baseline tokens drop to the outline.
|
|
15
|
+
//
|
|
16
|
+
// This module is the single source both the prompt builder and the routine
|
|
17
|
+
// runner read from, so "what skills are in context" and "what images can the
|
|
18
|
+
// agent attach" never drift from what the prompt actually said.
|
|
19
|
+
import { loadSkill } from "./loader.js";
|
|
20
|
+
import { agentSkills } from "./declared.js";
|
|
21
|
+
import { skillOutline } from "./sections.js";
|
|
22
|
+
import { readSkillMedia, renderMediaManifest } from "./media.js";
|
|
23
|
+
|
|
24
|
+
// A skill whose body is at or under this many characters is injected whole.
|
|
25
|
+
// ~1800 chars ≈ 450 tokens — below that the card + a read_skill round trip
|
|
26
|
+
// would cost more than it saves.
|
|
27
|
+
export const EAGER_MAX_CHARS = 1800;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Load an agent's declared skills with everything the prompt and the runner
|
|
31
|
+
* need. Skills that fail to resolve are skipped (a stale `skills:` entry must
|
|
32
|
+
* not crash a run).
|
|
33
|
+
*
|
|
34
|
+
* @returns {Array<{
|
|
35
|
+
* slug:string, mode:'eager'|'lazy', body:string, description:string,
|
|
36
|
+
* outline:string[], media:Array, file:string
|
|
37
|
+
* }>}
|
|
38
|
+
*/
|
|
39
|
+
export function loadAgentSkills(project, agent) {
|
|
40
|
+
const out = [];
|
|
41
|
+
for (const slug of agentSkills(agent)) {
|
|
42
|
+
let skill;
|
|
43
|
+
try {
|
|
44
|
+
skill = loadSkill(slug, { projectPath: project?.path });
|
|
45
|
+
} catch {
|
|
46
|
+
continue; // stale entry — silently skip, never throw mid-run
|
|
47
|
+
}
|
|
48
|
+
const body = String(skill.body || "").trim();
|
|
49
|
+
const media = readSkillMedia(skill);
|
|
50
|
+
// A skill with images is a large skill by nature (you page through it), so
|
|
51
|
+
// it goes lazy even if the text is short — that is exactly when the media
|
|
52
|
+
// manifest + read_skill pay off.
|
|
53
|
+
const mode = body.length <= EAGER_MAX_CHARS && media.length === 0 ? "eager" : "lazy";
|
|
54
|
+
out.push({
|
|
55
|
+
slug,
|
|
56
|
+
mode,
|
|
57
|
+
body,
|
|
58
|
+
description: skill.description || "",
|
|
59
|
+
outline: skillOutline(body),
|
|
60
|
+
media,
|
|
61
|
+
file: skill.file || "",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The system-prompt block for a set of loaded skills. Eager skills print full;
|
|
69
|
+
* lazy skills print a card (description + outline + image manifest) plus the
|
|
70
|
+
* one-line instruction for how to pull more.
|
|
71
|
+
*/
|
|
72
|
+
export function renderAgentSkillsBlock(loaded) {
|
|
73
|
+
const parts = [];
|
|
74
|
+
for (const s of loaded) {
|
|
75
|
+
if (s.mode === "eager") {
|
|
76
|
+
parts.push(`## Skill: ${s.slug}\n${s.body}`);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const lines = [`## Skill: ${s.slug} (loaded on demand)`];
|
|
80
|
+
if (s.description) lines.push(s.description);
|
|
81
|
+
if (s.outline.length) {
|
|
82
|
+
lines.push(
|
|
83
|
+
"Sections (call `read_skill` with the skill slug and a section title/number to read one):",
|
|
84
|
+
...s.outline.map((t) => `- ${t}`),
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
const manifest = renderMediaManifest(s.media);
|
|
88
|
+
if (manifest) lines.push(manifest);
|
|
89
|
+
parts.push(lines.join("\n"));
|
|
90
|
+
}
|
|
91
|
+
return parts.join("\n\n");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Every image across an agent's loaded skills, flattened and tagged with its
|
|
96
|
+
* skill, for the runner to validate attach_media / view_media against and to
|
|
97
|
+
* hand to delivery. Only images whose file actually exists are returned.
|
|
98
|
+
*/
|
|
99
|
+
export function collectAgentSkillMedia(loaded) {
|
|
100
|
+
const out = [];
|
|
101
|
+
for (const s of loaded) {
|
|
102
|
+
for (const m of s.media) {
|
|
103
|
+
if (!m.exists) continue;
|
|
104
|
+
out.push({ skill: s.slug, id: m.id, path: m.path, caption: m.caption, mime: m.mime, file: m.file });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return out;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Compact "skills in context" summary for the turn record (visibility). */
|
|
111
|
+
export function skillsInContextSummary(loaded) {
|
|
112
|
+
return loaded.map((s) => ({
|
|
113
|
+
slug: s.slug,
|
|
114
|
+
mode: s.mode,
|
|
115
|
+
sections: s.outline.length,
|
|
116
|
+
images: s.media.filter((m) => m.exists).length,
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// condensed description) is reached via the `list_skills` tool.
|
|
8
8
|
// 2. The `list_skills` tool itself renders descriptions using
|
|
9
9
|
// condenseSkillDescription() — keeps the trigger-list tails out of the
|
|
10
|
-
// tool result
|
|
10
|
+
// tool result.
|
|
11
11
|
//
|
|
12
12
|
// Skill descriptions are authored for Claude Code's skill matcher, so many end
|
|
13
13
|
// with verbose "Trigger on: …" / "Activate when …" / "Activa cuando…" lists.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Reading list-valued frontmatter fields off an agent card. Lives in its own
|
|
2
|
+
// module so both the prompt builder (build-agent-system.js) and the skill
|
|
3
|
+
// loader (agent-skills.js) can share it without an import cycle.
|
|
4
|
+
|
|
5
|
+
export function listField(value) {
|
|
6
|
+
if (Array.isArray(value)) return value.map(String).map((s) => s.trim()).filter(Boolean);
|
|
7
|
+
return String(value || "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** The skill slugs an agent declares in its `skills:` frontmatter. */
|
|
11
|
+
export function agentSkills(agent) {
|
|
12
|
+
return listField(agent?.fields?.Skills);
|
|
13
|
+
}
|
|
@@ -165,6 +165,13 @@ export async function ensureIndex({ projectPath, embedOpts = {}, onProgress, for
|
|
|
165
165
|
const embedder = embedderTag(probe);
|
|
166
166
|
const dim = probe.vector.length;
|
|
167
167
|
|
|
168
|
+
// Pin every per-skill embed to the engine the probe actually landed on, so a
|
|
169
|
+
// chain that fell past a rate-limited provider to a working one doesn't
|
|
170
|
+
// re-probe (and re-fail) the dead provider once per skill.
|
|
171
|
+
const embedPinned = embedder === "tf"
|
|
172
|
+
? { ...embedOpts, forceTf: true }
|
|
173
|
+
: { ...embedOpts, provider: embedder.split(":")[0] };
|
|
174
|
+
|
|
168
175
|
const embedderChanged = !force && idxBefore.embedder && idxBefore.embedder !== embedder;
|
|
169
176
|
const items = embedderChanged || force ? {} : structuredClone(idxBefore.items || {});
|
|
170
177
|
|
|
@@ -191,7 +198,7 @@ export async function ensureIndex({ projectPath, embedOpts = {}, onProgress, for
|
|
|
191
198
|
kept.push(s.slug);
|
|
192
199
|
action = "kept";
|
|
193
200
|
} else {
|
|
194
|
-
const out = await embedOne(desc,
|
|
201
|
+
const out = await embedOne(desc, embedPinned);
|
|
195
202
|
const vector = Array.isArray(out?.vector) ? out.vector : [];
|
|
196
203
|
items[s.slug] = {
|
|
197
204
|
slug: s.slug,
|
|
@@ -100,7 +100,10 @@ function renderInjectedBlock({ loaded, hinted, embedder }) {
|
|
|
100
100
|
if (hinted.length) {
|
|
101
101
|
lines.push("## Possibly relevant — load on demand");
|
|
102
102
|
for (const s of hinted) {
|
|
103
|
-
|
|
103
|
+
// A description read from a block scalar carries real newlines; this is
|
|
104
|
+
// one markdown list item, so collapse it back to a single line.
|
|
105
|
+
const desc = String(s.desc || "").replace(/\s+/g, " ").trim();
|
|
106
|
+
lines.push(`- \`${s.slug}\` — sim ${s.sim.toFixed(2)}. ${desc}`);
|
|
104
107
|
}
|
|
105
108
|
lines.push("");
|
|
106
109
|
lines.push("Call `load_skill({slug:\"…\"})` for any of these BEFORE answering if you need its exact syntax.");
|
|
@@ -174,9 +177,23 @@ export async function inspectPromptForSkills({ prompt, projectPath, globalConfig
|
|
|
174
177
|
return { contextNote: "", trace: { enabled: true, reason: "embed_failed" } };
|
|
175
178
|
}
|
|
176
179
|
|
|
177
|
-
// Embedder mismatch —
|
|
178
|
-
//
|
|
180
|
+
// Embedder mismatch — the index was built with a different provider (e.g. the
|
|
181
|
+
// local Ollama server was up when it was indexed and is now down, so we fell
|
|
182
|
+
// back to `tf`). Cosine only means anything within one embedder space, so we
|
|
183
|
+
// can't score this turn. But the line-156 refresh can't detect this on its own
|
|
184
|
+
// (it runs before we know the request-time embedder), so kick a rebuild HERE
|
|
185
|
+
// with the embedder we just probed: planIndex sees embedderChanged and rebuilds
|
|
186
|
+
// the index to the current space, and the NEXT turn scores normally. Without
|
|
187
|
+
// this the mismatch stuck silently until a daemon reboot or `apx skills index`
|
|
188
|
+
// — which is exactly how skill suggestions "just stopped appearing".
|
|
179
189
|
if (idx.embedder && idx.embedder !== probe.embedder) {
|
|
190
|
+
try {
|
|
191
|
+
backgroundRefreshIfStale({
|
|
192
|
+
projectPath,
|
|
193
|
+
embedOpts: { ...(embedOpts || {}), globalConfig },
|
|
194
|
+
currentEmbedder: probe.embedder,
|
|
195
|
+
});
|
|
196
|
+
} catch { /* best-effort */ }
|
|
180
197
|
return {
|
|
181
198
|
contextNote: "",
|
|
182
199
|
trace: {
|
|
@@ -34,6 +34,7 @@ import { SKILLS_DIR } from "#core/config/paths.js";
|
|
|
34
34
|
import { fileURLToPath } from "node:url";
|
|
35
35
|
import { apcSkillsDir } from "#core/apc/paths.js";
|
|
36
36
|
import { parseFrontmatter } from "#core/apc/frontmatter.js";
|
|
37
|
+
import { skillOrigin } from "./origin.js";
|
|
37
38
|
|
|
38
39
|
const __filename = fileURLToPath(import.meta.url);
|
|
39
40
|
const __dirname = path.dirname(__filename);
|
|
@@ -56,7 +57,15 @@ const GLOBAL_DIR = SKILLS_DIR;
|
|
|
56
57
|
// Directory scanners
|
|
57
58
|
// ---------------------------------------------------------------------------
|
|
58
59
|
|
|
59
|
-
/** Returns [{slug, source, file}] from a directory using <slug>/SKILL.md layout.
|
|
60
|
+
/** Returns [{slug, source, file}] from a directory using <slug>/SKILL.md layout.
|
|
61
|
+
*
|
|
62
|
+
* Symlinked entries count. `readdirSync({withFileTypes:true})` reports a
|
|
63
|
+
* symlink-to-directory as isSymbolicLink() and NOT isDirectory(), so testing
|
|
64
|
+
* isDirectory() alone silently skipped any skill linked in from somewhere
|
|
65
|
+
* else — the natural way to keep a skill managed by an external tool
|
|
66
|
+
* (`npx skills add` installs to ~/.agents/skills/) without copying it. The
|
|
67
|
+
* existsSync() below follows the link, so a broken link or a link to a file
|
|
68
|
+
* still drops out. */
|
|
60
69
|
function scanDirStyle(baseDir, source) {
|
|
61
70
|
if (!baseDir || !fs.existsSync(baseDir)) return [];
|
|
62
71
|
const out = [];
|
|
@@ -64,7 +73,7 @@ function scanDirStyle(baseDir, source) {
|
|
|
64
73
|
try { entries = fs.readdirSync(baseDir, { withFileTypes: true }); }
|
|
65
74
|
catch { return []; }
|
|
66
75
|
for (const e of entries) {
|
|
67
|
-
if (!e.isDirectory()) continue;
|
|
76
|
+
if (!e.isDirectory() && !e.isSymbolicLink()) continue;
|
|
68
77
|
const file = path.join(baseDir, e.name, "SKILL.md");
|
|
69
78
|
if (fs.existsSync(file)) out.push({ slug: e.name, source, file });
|
|
70
79
|
}
|
|
@@ -79,8 +88,10 @@ function scanFlatStyle(baseDir, source) {
|
|
|
79
88
|
try { entries = fs.readdirSync(baseDir, { withFileTypes: true }); }
|
|
80
89
|
catch { return []; }
|
|
81
90
|
for (const e of entries) {
|
|
82
|
-
if (!e.isFile()
|
|
91
|
+
if (!e.isFile() && !e.isSymbolicLink()) continue; // see scanDirStyle
|
|
92
|
+
if (!e.name.endsWith(".md")) continue;
|
|
83
93
|
if (e.name === "README.md") continue;
|
|
94
|
+
if (e.isSymbolicLink() && !fs.statSync(path.join(baseDir, e.name), { throwIfNoEntry: false })?.isFile()) continue;
|
|
84
95
|
out.push({
|
|
85
96
|
slug: e.name.replace(/\.md$/, ""),
|
|
86
97
|
source,
|
|
@@ -138,6 +149,7 @@ export function listSkills({ projectPath } = {}) {
|
|
|
138
149
|
source: entry.source,
|
|
139
150
|
description,
|
|
140
151
|
file: entry.file,
|
|
152
|
+
...skillOrigin(entry.file, { source: entry.source }),
|
|
141
153
|
});
|
|
142
154
|
}
|
|
143
155
|
return result;
|
|
@@ -170,6 +182,9 @@ export function loadSkill(slug, { projectPath } = {}) {
|
|
|
170
182
|
description: entry.description || fm.description || "",
|
|
171
183
|
frontmatter: fm,
|
|
172
184
|
body: body.trim(),
|
|
185
|
+
origin: entry.origin,
|
|
186
|
+
origin_path: entry.origin_path,
|
|
187
|
+
file_path: entry.file_path,
|
|
173
188
|
};
|
|
174
189
|
}
|
|
175
190
|
|