@phuetz/code-buddy 2.0.0 → 2.2.0
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/README.fr.md +56 -0
- package/README.md +74 -16
- package/codebuddy-runtime.json +5 -5
- package/dist/agent/codebuddy-agent.d.ts +18 -0
- package/dist/agent/codebuddy-agent.js +45 -8
- package/dist/agent/execution/agent-executor.d.ts +0 -9
- package/dist/agent/execution/agent-executor.js +176 -12
- package/dist/agent/execution/context-pipeline.d.ts +9 -0
- package/dist/agent/execution/context-pipeline.js +64 -2
- package/dist/agent/execution/tool-loop-guard.d.ts +76 -0
- package/dist/agent/execution/tool-loop-guard.js +165 -0
- package/dist/agent/execution/tool-selection-strategy.d.ts +7 -0
- package/dist/agent/execution/tool-selection-strategy.js +32 -2
- package/dist/agent/facades/session-facade.d.ts +0 -6
- package/dist/agent/facades/session-facade.js +0 -45
- package/dist/agent/hermes-claw-migrate.d.ts +0 -21
- package/dist/agent/hermes-claw-migrate.js +9 -4
- package/dist/agent/hermes-protocol-gateways.js +8 -1
- package/dist/agent/repo-profiler.js +17 -4
- package/dist/agent/self-improvement/authored-tool-runtime.js +10 -2
- package/dist/agent/self-improvement/evolution/ast-novelty.d.ts +5 -0
- package/dist/agent/self-improvement/evolution/ast-novelty.js +58 -23
- package/dist/agent/self-improvement/evolution/code-variant-store.d.ts +3 -0
- package/dist/agent/self-improvement/evolution/evolution-engine.js +2 -0
- package/dist/agent/self-improvement/evolution/protected-paths.js +6 -0
- package/dist/agent/self-improvement/evolution/variant-fitness.d.ts +13 -2
- package/dist/agent/self-improvement/evolution/variant-fitness.js +184 -58
- package/dist/agent/self-improvement/evolution/worktree-scorer.d.ts +2 -0
- package/dist/agent/self-improvement/evolution/worktree-scorer.js +15 -0
- package/dist/agent/self-improvement/evolutionary-archive.d.ts +2 -1
- package/dist/agent/self-improvement/evolutionary-archive.js +34 -5
- package/dist/agent/self-improvement/proposal-store.d.ts +1 -0
- package/dist/agent/self-improvement/proposal-store.js +79 -17
- package/dist/agent/self-improvement/skill-apply-journal.d.ts +44 -0
- package/dist/agent/self-improvement/skill-apply-journal.js +178 -0
- package/dist/agent/self-improvement/skill-behavior-benchmark.d.ts +3 -0
- package/dist/agent/self-improvement/skill-behavior-benchmark.js +19 -0
- package/dist/agent/self-improvement/skill-behavior-gate.d.ts +34 -0
- package/dist/agent/self-improvement/skill-behavior-gate.js +96 -0
- package/dist/agent/self-improvement/skill-engine.d.ts +22 -0
- package/dist/agent/self-improvement/skill-engine.js +385 -13
- package/dist/agent/self-improvement/skill-gate.d.ts +2 -0
- package/dist/agent/self-improvement/skill-gate.js +17 -2
- package/dist/agent/self-improvement/skill-mutator.d.ts +6 -1
- package/dist/agent/self-improvement/skill-mutator.js +51 -15
- package/dist/agent/self-improvement/skill-types.d.ts +2 -1
- package/dist/agent/self-improvement/types.d.ts +11 -0
- package/dist/agent/tool-handler.d.ts +1 -1
- package/dist/agent/tool-handler.js +28 -9
- package/dist/auth/profile-manager.js +1 -1
- package/dist/channels/companion-channel-turn.d.ts +53 -4
- package/dist/channels/companion-channel-turn.js +218 -16
- package/dist/channels/slash-parity.d.ts +4 -6
- package/dist/channels/slash-parity.js +9 -44
- package/dist/cli/session-commands.d.ts +9 -0
- package/dist/cli/session-commands.js +45 -5
- package/dist/cli/session-picker.d.ts +43 -0
- package/dist/cli/session-picker.js +128 -0
- package/dist/codebuddy/a2a-call-tool-defs.d.ts +26 -0
- package/dist/codebuddy/a2a-call-tool-defs.js +12 -0
- package/dist/codebuddy/fleet-tool-defs.d.ts +2 -0
- package/dist/codebuddy/fleet-tool-defs.js +55 -0
- package/dist/codebuddy/providers/chatgpt-headers.d.ts +18 -0
- package/dist/codebuddy/providers/chatgpt-headers.js +37 -0
- package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +2 -1
- package/dist/codebuddy/providers/provider-chatgpt-responses.js +10 -23
- package/dist/codebuddy/providers/provider-openai-compat.d.ts +7 -0
- package/dist/codebuddy/providers/provider-openai-compat.js +29 -1
- package/dist/codebuddy/ragchat-tool-defs.d.ts +31 -0
- package/dist/codebuddy/ragchat-tool-defs.js +19 -0
- package/dist/codebuddy/resource-catalog-tool-defs.d.ts +28 -0
- package/dist/codebuddy/resource-catalog-tool-defs.js +18 -0
- package/dist/codebuddy/tool-definitions/agent-tools.js +2 -2
- package/dist/codebuddy/tool-definitions/code-exec-tools.js +5 -1
- package/dist/codebuddy/tool-definitions/cron-tools.js +6 -0
- package/dist/codebuddy/tool-definitions/self-describe-tools.js +6 -1
- package/dist/codebuddy/tools.d.ts +0 -6
- package/dist/codebuddy/tools.js +25 -3
- package/dist/commands/cli/daemon-commands.js +3 -1
- package/dist/commands/cli/evolve-command.js +21 -5
- package/dist/commands/cli/fleet-collaboration-commands.d.ts +2 -0
- package/dist/commands/cli/fleet-collaboration-commands.js +57 -0
- package/dist/commands/cli/fleet-commands.js +29 -0
- package/dist/commands/cli/fleet-mission-commands.d.ts +3 -0
- package/dist/commands/cli/fleet-mission-commands.js +72 -0
- package/dist/commands/cli/fleet-rooms-commands.d.ts +10 -0
- package/dist/commands/cli/fleet-rooms-commands.js +289 -0
- package/dist/commands/cli/tools-commands.js +2 -1
- package/dist/commands/cli/triage-command.d.ts +8 -0
- package/dist/commands/cli/triage-command.js +72 -0
- package/dist/commands/cli/utility-commands.js +25 -1
- package/dist/commands/client-dispatcher.d.ts +7 -0
- package/dist/commands/client-dispatcher.js +73 -21
- package/dist/commands/cron-cli/index.d.ts +3 -1
- package/dist/commands/cron-cli/index.js +25 -0
- package/dist/commands/device-auth.d.ts +10 -0
- package/dist/commands/device-auth.js +91 -0
- package/dist/commands/enhanced-command-handler.d.ts +9 -0
- package/dist/commands/enhanced-command-handler.js +28 -6
- package/dist/commands/handlers/agent-handlers.d.ts +1 -1
- package/dist/commands/handlers/agent-handlers.js +4 -4
- package/dist/commands/handlers/channel-handlers.js +53 -2
- package/dist/commands/handlers/export-handlers.d.ts +3 -2
- package/dist/commands/handlers/export-handlers.js +55 -28
- package/dist/commands/handlers/extra-handlers.js +5 -1
- package/dist/commands/handlers/grill-me-handler.js +26 -18
- package/dist/commands/handlers/memory-handlers.d.ts +6 -2
- package/dist/commands/handlers/memory-handlers.js +35 -15
- package/dist/commands/handlers/missing-handlers.d.ts +2 -2
- package/dist/commands/handlers/missing-handlers.js +12 -4
- package/dist/commands/handlers/resources-handler.d.ts +12 -0
- package/dist/commands/handlers/resources-handler.js +52 -0
- package/dist/commands/handlers/starter-handlers.d.ts +1 -1
- package/dist/commands/handlers/starter-handlers.js +32 -2
- package/dist/commands/handlers/switch-handler.d.ts +1 -1
- package/dist/commands/handlers/switch-handler.js +15 -0
- package/dist/commands/handlers/test-handlers.js +4 -86
- package/dist/commands/handlers/ui-handlers.js +11 -5
- package/dist/commands/login-chatgpt.d.ts +8 -0
- package/dist/commands/login-chatgpt.js +17 -0
- package/dist/commands/mcp-import.d.ts +11 -0
- package/dist/commands/mcp-import.js +67 -0
- package/dist/commands/mcp-invoke.d.ts +2 -0
- package/dist/commands/mcp-invoke.js +68 -0
- package/dist/commands/mcp.d.ts +13 -0
- package/dist/commands/mcp.js +66 -21
- package/dist/commands/pipeline.d.ts +7 -1
- package/dist/commands/pipeline.js +104 -7
- package/dist/commands/resources.d.ts +2 -0
- package/dist/commands/resources.js +64 -0
- package/dist/commands/skills-cli/index.js +35 -12
- package/dist/commands/slash/builtin-commands.js +16 -3
- package/dist/commands/slash/index.d.ts +3 -1
- package/dist/commands/slash/index.js +2 -0
- package/dist/commands/slash/surfaces.d.ts +53 -0
- package/dist/commands/slash/surfaces.js +177 -0
- package/dist/commands/slash/types.d.ts +17 -0
- package/dist/commands/try.d.ts +1 -1
- package/dist/commands/try.js +1 -1
- package/dist/companion/companion-identity.d.ts +43 -0
- package/dist/companion/companion-identity.js +136 -0
- package/dist/companion/companion-toolset.d.ts +66 -0
- package/dist/companion/companion-toolset.js +368 -0
- package/dist/companion/companion-turn.d.ts +10 -2
- package/dist/companion/companion-turn.js +38 -1
- package/dist/config/code-exec-policy.d.ts +25 -0
- package/dist/config/code-exec-policy.js +39 -0
- package/dist/config/model-tools.d.ts +9 -0
- package/dist/config/model-tools.js +103 -0
- package/dist/context/context-manager-v2.js +2 -2
- package/dist/context/lm-resizer-compressor.js +3 -2
- package/dist/context/lm-resizer-diagnostics.d.ts +9 -0
- package/dist/context/lm-resizer-diagnostics.js +30 -0
- package/dist/context/tool-output-masking.js +3 -4
- package/dist/curator/curator.d.ts +6 -0
- package/dist/curator/curator.js +53 -3
- package/dist/daemon/cron-agent-bridge.d.ts +6 -0
- package/dist/daemon/cron-agent-bridge.js +31 -4
- package/dist/doctor/index.d.ts +11 -2
- package/dist/doctor/index.js +84 -21
- package/dist/doctor/integrations.d.ts +197 -0
- package/dist/doctor/integrations.js +241 -0
- package/dist/doctor/triage.d.ts +108 -0
- package/dist/doctor/triage.js +304 -0
- package/dist/errors/crash-handler.js +2 -0
- package/dist/fleet/collaboration.d.ts +44 -0
- package/dist/fleet/collaboration.js +170 -0
- package/dist/fleet/fleet-listener.d.ts +1 -0
- package/dist/fleet/fleet-listener.js +87 -46
- package/dist/fleet/fleet-registry.d.ts +2 -0
- package/dist/fleet/resource-catalog.d.ts +245 -0
- package/dist/fleet/resource-catalog.js +211 -0
- package/dist/fleet/rooms/room-access.d.ts +138 -0
- package/dist/fleet/rooms/room-access.js +196 -0
- package/dist/fleet/rooms/room-client.d.ts +158 -0
- package/dist/fleet/rooms/room-client.js +685 -0
- package/dist/fleet/rooms/room-event.d.ts +139 -0
- package/dist/fleet/rooms/room-event.js +330 -0
- package/dist/fleet/rooms/room-filter.d.ts +48 -0
- package/dist/fleet/rooms/room-filter.js +152 -0
- package/dist/fleet/rooms/room-hub.d.ts +154 -0
- package/dist/fleet/rooms/room-hub.js +363 -0
- package/dist/fleet/rooms/room-identity.d.ts +26 -0
- package/dist/fleet/rooms/room-identity.js +82 -0
- package/dist/fleet/rooms/room-lock.d.ts +34 -0
- package/dist/fleet/rooms/room-lock.js +180 -0
- package/dist/fleet/rooms/room-observations.d.ts +7 -0
- package/dist/fleet/rooms/room-observations.js +61 -0
- package/dist/fleet/rooms/room-server.d.ts +28 -0
- package/dist/fleet/rooms/room-server.js +75 -0
- package/dist/fleet/rooms/room-store.d.ts +119 -0
- package/dist/fleet/rooms/room-store.js +448 -0
- package/dist/fleet/rooms/room-ws-bridge.d.ts +27 -0
- package/dist/fleet/rooms/room-ws-bridge.js +137 -0
- package/dist/fleet/sensory-mission-bridge.d.ts +42 -0
- package/dist/fleet/sensory-mission-bridge.js +136 -0
- package/dist/git/worktree-sessions.js +1 -0
- package/dist/harness/contract.d.ts +4 -4
- package/dist/harness/fleet-supervisor.d.ts +16 -0
- package/dist/harness/fleet-supervisor.js +64 -0
- package/dist/harness/index.d.ts +4 -0
- package/dist/harness/index.js +4 -0
- package/dist/harness/mission-runner.d.ts +3 -0
- package/dist/harness/mission-runner.js +53 -0
- package/dist/harness/mission-store.d.ts +93 -0
- package/dist/harness/mission-store.js +297 -0
- package/dist/harness/tool-harness.d.ts +56 -0
- package/dist/harness/tool-harness.js +153 -0
- package/dist/hooks/use-enhanced-input.js +48 -4
- package/dist/hooks/use-input-handler.d.ts +1 -0
- package/dist/hooks/use-input-handler.js +82 -22
- package/dist/hooks/use-input-history.js +1 -0
- package/dist/identity/lisa-introspection.js +5 -2
- package/dist/identity/operational-self-model.d.ts +2 -0
- package/dist/identity/operational-self-model.js +4 -0
- package/dist/index.js +52 -6
- package/dist/mcp/client.d.ts +11 -0
- package/dist/mcp/client.js +68 -3
- package/dist/mcp/config.d.ts +20 -0
- package/dist/mcp/config.js +121 -8
- package/dist/mcp/import-normalize.d.ts +12 -0
- package/dist/mcp/import-normalize.js +114 -0
- package/dist/mcp/mcp-oauth-constants.d.ts +8 -0
- package/dist/mcp/mcp-oauth-constants.js +9 -0
- package/dist/mcp/mcp-oauth-provider.d.ts +80 -0
- package/dist/mcp/mcp-oauth-provider.js +241 -0
- package/dist/mcp/mcp-oauth.d.ts +60 -1
- package/dist/mcp/mcp-oauth.js +241 -65
- package/dist/mcp/transports.d.ts +14 -5
- package/dist/mcp/transports.js +112 -101
- package/dist/mcp/types.d.ts +5 -0
- package/dist/media/comfyui-recipe-contract.d.ts +7 -7
- package/dist/memory/facts-memory.d.ts +11 -1
- package/dist/memory/facts-memory.js +47 -8
- package/dist/memory/memory-candidate-queue.d.ts +2 -2
- package/dist/memory/memory-candidate-queue.js +6 -6
- package/dist/memory/persistent-memory.d.ts +13 -8
- package/dist/memory/persistent-memory.js +77 -30
- package/dist/nodes/device-node.js +5 -9
- package/dist/observability/mobile-supervision-gateway-contract.js +20 -7
- package/dist/observability/run-event-writer.d.ts +21 -0
- package/dist/observability/run-event-writer.js +81 -0
- package/dist/observability/run-store.d.ts +5 -0
- package/dist/observability/run-store.js +18 -13
- package/dist/observability/run-trajectory.js +1 -1
- package/dist/optimization/prompt-cache.d.ts +19 -2
- package/dist/optimization/prompt-cache.js +41 -6
- package/dist/orchestration/orchestrator.d.ts +21 -0
- package/dist/orchestration/orchestrator.js +122 -15
- package/dist/persistence/session-content.d.ts +8 -0
- package/dist/persistence/session-content.js +76 -0
- package/dist/persistence/session-handoff.d.ts +64 -0
- package/dist/persistence/session-handoff.js +80 -0
- package/dist/persistence/session-history.d.ts +4 -0
- package/dist/persistence/session-history.js +38 -0
- package/dist/persistence/session-store.d.ts +9 -0
- package/dist/persistence/session-store.js +48 -20
- package/dist/personas/persona-manager.js +17 -1
- package/dist/plugins/code-explorer/CodeExplorerManager.d.ts +10 -4
- package/dist/plugins/code-explorer/CodeExplorerManager.js +69 -16
- package/dist/plugins/plugin-manager.js +10 -1
- package/dist/prompts/prompt-manager.js +11 -4
- package/dist/prompts/system-base.js +6 -2
- package/dist/protocols/a2a/codebuddy-executor.d.ts +11 -2
- package/dist/protocols/a2a/codebuddy-executor.js +9 -8
- package/dist/protocols/a2a/index.d.ts +1 -1
- package/dist/protocols/a2a/jsonrpc-v1.d.ts +41 -0
- package/dist/protocols/a2a/jsonrpc-v1.js +145 -0
- package/dist/protocols/a2a/peer-config.d.ts +20 -0
- package/dist/protocols/a2a/peer-config.js +55 -0
- package/dist/providers/codex-oauth.js +30 -6
- package/dist/providers/model-provider-compat.js +2 -1
- package/dist/sandbox/os-sandbox.d.ts +1 -1
- package/dist/scheduler/cron-scheduler.d.ts +15 -2
- package/dist/scheduler/cron-scheduler.js +35 -4
- package/dist/scheduler/job-notepad.d.ts +69 -0
- package/dist/scheduler/job-notepad.js +339 -0
- package/dist/security/audit-logger.d.ts +1 -1
- package/dist/security/compute-confinement.d.ts +4 -0
- package/dist/security/compute-confinement.js +89 -0
- package/dist/security/session-encryption.d.ts +4 -0
- package/dist/security/session-encryption.js +31 -0
- package/dist/sensory/voice-loop.d.ts +17 -0
- package/dist/sensory/voice-loop.js +72 -15
- package/dist/server/auth/device-session-context.d.ts +9 -0
- package/dist/server/auth/device-session-context.js +13 -0
- package/dist/server/auth/device-store.d.ts +89 -0
- package/dist/server/auth/device-store.js +261 -0
- package/dist/server/auth/device-token.d.ts +3 -0
- package/dist/server/auth/device-token.js +6 -0
- package/dist/server/auth/jwt.js +4 -0
- package/dist/server/index.d.ts +0 -10
- package/dist/server/index.js +28 -0
- package/dist/server/middleware/auth.js +3 -2
- package/dist/server/routes/a2a-jsonrpc.d.ts +9 -0
- package/dist/server/routes/a2a-jsonrpc.js +66 -0
- package/dist/server/routes/a2a-protocol.d.ts +12 -0
- package/dist/server/routes/a2a-protocol.js +1 -1
- package/dist/server/routes/device-auth.d.ts +4 -0
- package/dist/server/routes/device-auth.js +40 -0
- package/dist/server/types.d.ts +4 -0
- package/dist/server/websocket/handler.d.ts +13 -0
- package/dist/server/websocket/handler.js +102 -17
- package/dist/services/prompt-builder.d.ts +2 -0
- package/dist/services/prompt-builder.js +16 -6
- package/dist/services/runtime-settings-context.d.ts +81 -0
- package/dist/services/runtime-settings-context.js +79 -0
- package/dist/skills/executor.js +2 -0
- package/dist/skills/hub.js +16 -14
- package/dist/skills/local-inventory.d.ts +21 -0
- package/dist/skills/local-inventory.js +72 -0
- package/dist/skills/skill-loader.js +2 -2
- package/dist/skills/skill-usage-store.d.ts +49 -0
- package/dist/skills/skill-usage-store.js +121 -0
- package/dist/testing/ai-integration-tests.js +8 -5
- package/dist/themes/theme-manager.d.ts +12 -0
- package/dist/themes/theme-manager.js +29 -0
- package/dist/themes/theme-schema.d.ts +24 -24
- package/dist/tools/a2a-call-tool.d.ts +34 -0
- package/dist/tools/a2a-call-tool.js +75 -0
- package/dist/tools/bash/streaming-executor.d.ts +1 -0
- package/dist/tools/bash/streaming-executor.js +78 -90
- package/dist/tools/code-exec-preflight-runner.d.ts +41 -0
- package/dist/tools/code-exec-preflight-runner.js +254 -0
- package/dist/tools/code-exec-preflight.d.ts +44 -0
- package/dist/tools/code-exec-preflight.js +501 -0
- package/dist/tools/code-exec-tool.d.ts +48 -1
- package/dist/tools/code-exec-tool.js +191 -47
- package/dist/tools/comment-watcher.js +29 -12
- package/dist/tools/core-code-inspection.d.ts +56 -0
- package/dist/tools/core-code-inspection.js +86 -0
- package/dist/tools/create-skill-tool.d.ts +2 -3
- package/dist/tools/create-skill-tool.js +16 -75
- package/dist/tools/cronjob-tool.d.ts +1 -0
- package/dist/tools/cronjob-tool.js +1 -0
- package/dist/tools/env-doctor-tool.d.ts +2 -0
- package/dist/tools/env-doctor-tool.js +4 -3
- package/dist/tools/execute-code-rpc-invoker.d.ts +1 -1
- package/dist/tools/execute-code-rpc-invoker.js +35 -19
- package/dist/tools/execute-code-runner.d.ts +2 -0
- package/dist/tools/execute-code-runner.js +52 -17
- package/dist/tools/fleet-room-tool.d.ts +104 -0
- package/dist/tools/fleet-room-tool.js +124 -0
- package/dist/tools/integration-tool-hints.d.ts +4 -0
- package/dist/tools/integration-tool-hints.js +19 -0
- package/dist/tools/list-peers-tool.d.ts +3 -0
- package/dist/tools/list-peers-tool.js +11 -4
- package/dist/tools/media-generation-tool.d.ts +16 -1
- package/dist/tools/media-generation-tool.js +341 -9
- package/dist/tools/merge-conflict-tool.js +53 -25
- package/dist/tools/metadata.d.ts +1 -5
- package/dist/tools/metadata.js +30 -28
- package/dist/tools/peer-tool-invoke-tool.d.ts +61 -0
- package/dist/tools/peer-tool-invoke-tool.js +396 -0
- package/dist/tools/ragchat-tool.d.ts +39 -0
- package/dist/tools/ragchat-tool.js +105 -0
- package/dist/tools/registry/fleet-tools.d.ts +21 -3
- package/dist/tools/registry/fleet-tools.js +137 -4
- package/dist/tools/registry/index.d.ts +1 -1
- package/dist/tools/registry/index.js +2 -2
- package/dist/tools/registry/knowledge-tools.d.ts +2 -2
- package/dist/tools/registry/knowledge-tools.js +2 -2
- package/dist/tools/registry/lessons-tools.d.ts +7 -0
- package/dist/tools/registry/lessons-tools.js +43 -3
- package/dist/tools/registry/memory-tools.d.ts +1 -1
- package/dist/tools/registry/memory-tools.js +8 -8
- package/dist/tools/registry/research-tools.d.ts +1 -0
- package/dist/tools/registry/research-tools.js +4 -13
- package/dist/tools/registry/self-describe-tools.d.ts +1 -1
- package/dist/tools/registry/self-describe-tools.js +43 -30
- package/dist/tools/resource-catalog-tool.d.ts +38 -0
- package/dist/tools/resource-catalog-tool.js +46 -0
- package/dist/tools/skills-inspection-tool.js +30 -1
- package/dist/tools/stream-tool-output.d.ts +3 -0
- package/dist/tools/stream-tool-output.js +33 -0
- package/dist/tools/tool-call-scheduler.d.ts +10 -0
- package/dist/tools/tool-call-scheduler.js +58 -0
- package/dist/tools/tool-effect.d.ts +5 -0
- package/dist/tools/tool-effect.js +26 -0
- package/dist/tools/tool-search.d.ts +12 -11
- package/dist/tools/tool-search.js +67 -26
- package/dist/tools/types.d.ts +6 -0
- package/dist/ui/components/ChatHistory.d.ts +1 -1
- package/dist/ui/components/ChatHistory.js +2 -2
- package/dist/ui/components/ChatInput.d.ts +2 -1
- package/dist/ui/components/ChatInput.js +42 -88
- package/dist/ui/components/ChatInterface.d.ts +4 -2
- package/dist/ui/components/ChatInterface.js +27 -63
- package/dist/ui/components/CommandSuggestions.d.ts +0 -1
- package/dist/ui/components/CommandSuggestions.js +4 -6
- package/dist/ui/components/FileAutocomplete.js +1 -1
- package/dist/ui/components/KeyboardHelp.js +8 -6
- package/dist/ui/components/ModelSelection.js +6 -5
- package/dist/ui/components/StatusBar.d.ts +2 -1
- package/dist/ui/components/StatusBar.js +8 -7
- package/dist/ui/context/theme-context.js +3 -2
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/utils/markdown-renderer.js +4 -13
- package/dist/utils/atomic-write.d.ts +22 -0
- package/dist/utils/atomic-write.js +29 -0
- package/dist/utils/bounded-output.d.ts +16 -0
- package/dist/utils/bounded-output.js +63 -0
- package/dist/utils/config-validation/schema.d.ts +2 -2
- package/dist/utils/device-store-file.d.ts +4 -0
- package/dist/utils/device-store-file.js +40 -0
- package/dist/utils/export-manager.d.ts +9 -0
- package/dist/utils/export-manager.js +19 -0
- package/dist/utils/first-use-hints.d.ts +25 -0
- package/dist/utils/first-use-hints.js +58 -0
- package/dist/utils/graceful-shutdown.d.ts +8 -0
- package/dist/utils/graceful-shutdown.js +23 -7
- package/dist/utils/history-manager.js +1 -1
- package/dist/utils/update-notifier.js +16 -18
- package/dist/wizard/environment-detection.d.ts +5 -1
- package/dist/wizard/environment-detection.js +49 -7
- package/dist/wizard/onboarding.d.ts +5 -1
- package/dist/wizard/onboarding.js +90 -30
- package/dist/wizard/provider-onboarding.d.ts +2 -0
- package/dist/wizard/provider-onboarding.js +55 -17
- package/package.json +7 -3
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* Commander actions stay thin wrappers around the scheduler singleton.
|
|
23
23
|
*/
|
|
24
24
|
import * as fs from 'fs';
|
|
25
|
+
import { validateContinuity } from '../../scheduler/job-notepad.js';
|
|
25
26
|
/**
|
|
26
27
|
* Build (and validate) a CronJob spec from CLI options. Pure: no side effects,
|
|
27
28
|
* fully unit-testable. Returns either a spec or a human-readable error.
|
|
@@ -77,6 +78,17 @@ export function buildCronJobSpec(name, opts) {
|
|
|
77
78
|
}
|
|
78
79
|
spec.then = opts.then.trim();
|
|
79
80
|
}
|
|
81
|
+
if (opts.continuity !== undefined) {
|
|
82
|
+
const parsed = parseJsonOption(opts.continuity, '--continuity');
|
|
83
|
+
if ('error' in parsed)
|
|
84
|
+
return parsed;
|
|
85
|
+
try {
|
|
86
|
+
spec.continuity = validateContinuity(parsed.value);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return { error: `Invalid --continuity: ${String(error)}` };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
80
92
|
// Optional pre-check gate.
|
|
81
93
|
if (opts.preCheck !== undefined) {
|
|
82
94
|
const parsed = parseJsonOption(opts.preCheck, '--pre-check');
|
|
@@ -159,6 +171,17 @@ export function buildCronJobUpdates(job, opts) {
|
|
|
159
171
|
}
|
|
160
172
|
updates.then = opts.then.trim();
|
|
161
173
|
}
|
|
174
|
+
if (opts.continuity !== undefined) {
|
|
175
|
+
const parsed = parseJsonOption(opts.continuity, '--continuity');
|
|
176
|
+
if ('error' in parsed)
|
|
177
|
+
return parsed;
|
|
178
|
+
try {
|
|
179
|
+
updates.continuity = validateContinuity(parsed.value);
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
return { error: `Invalid --continuity: ${String(error)}` };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
162
185
|
if (opts.preCheck !== undefined && opts.clearPreCheck) {
|
|
163
186
|
return { error: 'cron update: --pre-check and --clear-pre-check are mutually exclusive' };
|
|
164
187
|
}
|
|
@@ -394,6 +417,7 @@ export function registerCronCommands(program) {
|
|
|
394
417
|
.option('--skill-request <text>', 'request string passed to the skill executor')
|
|
395
418
|
.option('--then <jobId>', 'chain: run this job id (or prefix) on successful completion')
|
|
396
419
|
.option('--clear-then', 'remove the chain target')
|
|
420
|
+
.option('--continuity <json>', 'per-job continuity: true, false, or {enabled, notes}; inline JSON or @file')
|
|
397
421
|
.option('--pre-check <json>', 'replace pre-check gate as inline JSON or @file')
|
|
398
422
|
.option('--clear-pre-check', 'remove the pre-check gate')
|
|
399
423
|
.option('--deliver <target>', 'replace delivery targets type:id (repeatable)', collectOption, [])
|
|
@@ -433,6 +457,7 @@ export function registerCronCommands(program) {
|
|
|
433
457
|
.option('--skill <id>', 'no-agent skill run by registered skill name')
|
|
434
458
|
.option('--skill-request <text>', 'request string passed to the skill executor')
|
|
435
459
|
.option('--then <jobId>', 'chain: run this job id (or prefix) on successful completion')
|
|
460
|
+
.option('--continuity <json>', 'per-job continuity: true, false, or {enabled, notes}; inline JSON or @file')
|
|
436
461
|
.option('--pre-check <json>', 'pre-check gate as inline JSON or @file')
|
|
437
462
|
.option('--deliver <target>', 'delivery target type:id (repeatable)', collectOption, [])
|
|
438
463
|
.option('--format <fmt>', 'delivery body format: full|summary')
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { DeviceAuthStore } from '../server/auth/device-store.js';
|
|
3
|
+
import { type SpawnSyncFn } from './token.js';
|
|
4
|
+
export interface DeviceCommandDependencies {
|
|
5
|
+
store?: DeviceAuthStore;
|
|
6
|
+
env?: NodeJS.ProcessEnv;
|
|
7
|
+
spawn?: SpawnSyncFn;
|
|
8
|
+
}
|
|
9
|
+
export declare function createPairCommand(deps?: DeviceCommandDependencies): Command;
|
|
10
|
+
export declare function createDevicesCommand(deps?: DeviceCommandDependencies): Command;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { getDeviceAuthStore } from '../server/auth/device-store.js';
|
|
3
|
+
import { renderQrAnsi } from './token.js';
|
|
4
|
+
function pairingUrl(raw) {
|
|
5
|
+
try {
|
|
6
|
+
const url = new URL(raw);
|
|
7
|
+
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash)
|
|
8
|
+
throw new Error();
|
|
9
|
+
return url.toString().replace(/\/+$/, '');
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
throw new Error('Use a valid HTTP(S) server URL without credentials, query or fragment');
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function createPairCommand(deps = {}) {
|
|
16
|
+
return new Command('pair')
|
|
17
|
+
.description('Pair an Android authenticator with this server (local one-time code, 10 minutes)')
|
|
18
|
+
.option('--url <url>', 'Server URL reachable from the phone')
|
|
19
|
+
.option('--json', 'Print the QR payload as JSON')
|
|
20
|
+
.action((options) => {
|
|
21
|
+
try {
|
|
22
|
+
const env = deps.env ?? process.env;
|
|
23
|
+
const url = pairingUrl(options.url || env.CODEBUDDY_SERVER_URL || `http://127.0.0.1:${env.CODEBUDDY_SERVER_PORT || env.PORT || '3000'}`);
|
|
24
|
+
const { pairingCode, expiresAt } = (deps.store ?? getDeviceAuthStore()).createPairing();
|
|
25
|
+
const payload = JSON.stringify({ url, pairingCode });
|
|
26
|
+
if (options.json) {
|
|
27
|
+
console.log(payload);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
console.log(`Pairing code: ${pairingCode}`);
|
|
31
|
+
console.log(`Expires: ${expiresAt} (10 minutes, one use)`);
|
|
32
|
+
console.log(payload);
|
|
33
|
+
const qr = renderQrAnsi(payload, deps.spawn);
|
|
34
|
+
if (qr.ok)
|
|
35
|
+
console.log(qr.output);
|
|
36
|
+
else
|
|
37
|
+
console.error(qr.hint);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error(error instanceof Error && error.message.startsWith('Use a valid')
|
|
41
|
+
? error.message : 'Device pairing unavailable');
|
|
42
|
+
process.exitCode = 1;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
export function createDevicesCommand(deps = {}) {
|
|
47
|
+
const command = new Command('devices').description('Manage Android authentication devices (local only)');
|
|
48
|
+
const getStore = () => deps.store ?? getDeviceAuthStore();
|
|
49
|
+
command.command('list').option('--json', 'Print public device metadata as JSON')
|
|
50
|
+
.action((options) => {
|
|
51
|
+
try {
|
|
52
|
+
const devices = getStore().list().map(({ publicKeyJwk: _key, ...metadata }) => metadata);
|
|
53
|
+
if (options.json)
|
|
54
|
+
console.log(JSON.stringify(devices, null, 2));
|
|
55
|
+
else if (devices.length === 0)
|
|
56
|
+
console.log('No Android devices paired. Run buddy pair.');
|
|
57
|
+
else
|
|
58
|
+
for (const device of devices) {
|
|
59
|
+
console.log(`${device.deviceId} ${device.deviceName} ${device.revokedAt ? 'revoked' : 'active'} ${device.createdAt}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
console.error('Device store unavailable');
|
|
64
|
+
process.exitCode = 1;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
command.command('revoke <id>').description('Revoke an Android authentication device')
|
|
68
|
+
.action((id) => {
|
|
69
|
+
try {
|
|
70
|
+
getStore().revoke(id);
|
|
71
|
+
console.log('Device revoked');
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
console.error('Unable to revoke device');
|
|
75
|
+
process.exitCode = 1;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
command.command('rename <id> <name>').description('Rename an Android device')
|
|
79
|
+
.action((id, name) => {
|
|
80
|
+
try {
|
|
81
|
+
getStore().rename(id, name);
|
|
82
|
+
console.log('Device renamed');
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
console.error('Unable to rename device');
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return command;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=device-auth.js.map
|
|
@@ -2,10 +2,19 @@ import { ChatEntry } from "../agent/codebuddy-agent.js";
|
|
|
2
2
|
import { CodeBuddyClient } from "../codebuddy/client.js";
|
|
3
3
|
import type { CommandHandlerResult } from "./handlers/index.js";
|
|
4
4
|
export type { CommandHandlerResult };
|
|
5
|
+
/**
|
|
6
|
+
* Give every handled result a visible `entry` when the handler only produced
|
|
7
|
+
* legacy text fields. Results that already carry an entry are left untouched.
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizeHandlerResult(result: CommandHandlerResult): CommandHandlerResult;
|
|
5
10
|
/**
|
|
6
11
|
* Proxy interface for agent context stats used by the /context stats command.
|
|
7
12
|
*/
|
|
8
13
|
export interface AgentContextProxy {
|
|
14
|
+
getMemoryScope?: () => {
|
|
15
|
+
cwd: string;
|
|
16
|
+
botId?: string;
|
|
17
|
+
};
|
|
9
18
|
getContextStats: () => unknown;
|
|
10
19
|
formatContextStats: () => string;
|
|
11
20
|
getCurrentModel: () => string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { handleGrillMe } from './handlers/grill-me-handler.js';
|
|
2
2
|
import { handleDeepthink } from './handlers/deepthink-handler.js';
|
|
3
|
+
import { withFactsMemorySessionClient } from "../memory/facts-memory.js";
|
|
3
4
|
// Import all handlers from modular files
|
|
4
5
|
import {
|
|
5
6
|
// Branch handlers
|
|
@@ -116,6 +117,7 @@ handleInfra,
|
|
|
116
117
|
handleRedo, handleTimeline, handleKnowledgeGraph, handleApprovals, } from "./handlers/index.js";
|
|
117
118
|
import { handleLessonsCommand } from "./handlers/index.js";
|
|
118
119
|
import { handleContextStats } from "./handlers/extra-handlers.js";
|
|
120
|
+
import { handleResources } from "./handlers/resources-handler.js";
|
|
119
121
|
import { handleLogin, handleLogout, handleWhoami } from "./handlers/auth-handlers.js";
|
|
120
122
|
import { handlePromptCommand as handlePromptCommandRaw } from "./slash/prompt-commands.js";
|
|
121
123
|
import { handleShortcuts, handleDebugMode, handleToolAnalytics, handleSecurityReview, handleIdentity, handlePairing, handleElevated, handlePolicy, } from "./handlers/index.js";
|
|
@@ -183,6 +185,25 @@ async function handlePromptCommand(args) {
|
|
|
183
185
|
entry: { type: 'assistant', content: output, timestamp: new Date() },
|
|
184
186
|
};
|
|
185
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Give every handled result a visible `entry` when the handler only produced
|
|
190
|
+
* legacy text fields. Results that already carry an entry are left untouched.
|
|
191
|
+
*/
|
|
192
|
+
export function normalizeHandlerResult(result) {
|
|
193
|
+
if (!result.handled || result.entry) {
|
|
194
|
+
return result;
|
|
195
|
+
}
|
|
196
|
+
const legacy = result;
|
|
197
|
+
const text = [legacy.output, legacy.response, legacy.message, legacy.error]
|
|
198
|
+
.find((value) => typeof value === 'string' && value.trim().length > 0);
|
|
199
|
+
if (!text) {
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
...result,
|
|
204
|
+
entry: { type: 'assistant', content: text, timestamp: new Date() },
|
|
205
|
+
};
|
|
206
|
+
}
|
|
186
207
|
/**
|
|
187
208
|
* Enhanced Command Handler.
|
|
188
209
|
*
|
|
@@ -225,8 +246,8 @@ export class EnhancedCommandHandler {
|
|
|
225
246
|
['__MERGE__', (args) => handleMerge(args)],
|
|
226
247
|
['__BRANCH__', (args) => handleBranch(args)],
|
|
227
248
|
// Memory & TODOs
|
|
228
|
-
['__MEMORY__', (args) => handleMemory(args)],
|
|
229
|
-
['__REMEMBER__', (args) => handleRemember(args)],
|
|
249
|
+
['__MEMORY__', (args) => this.agentProxy?.getMemoryScope ? handleMemory(args, this.agentProxy.getMemoryScope()) : handleMemory(args)],
|
|
250
|
+
['__REMEMBER__', (args) => this.agentProxy?.getMemoryScope ? handleRemember(args, this.agentProxy.getMemoryScope()) : handleRemember(args)],
|
|
230
251
|
['__SCAN_TODOS__', () => handleScanTodos()],
|
|
231
252
|
['__ADDRESS_TODO__', (args) => handleAddressTodo(args)],
|
|
232
253
|
// Context & Workspace
|
|
@@ -237,7 +258,7 @@ export class EnhancedCommandHandler {
|
|
|
237
258
|
: handleContext(args)],
|
|
238
259
|
// Export (context-dependent: conversationHistory)
|
|
239
260
|
['__SAVE_CONVERSATION__', (args) => handleSaveConversation(args, this.conversationHistory)],
|
|
240
|
-
['__EXPORT__', (args) => handleExport(args)],
|
|
261
|
+
['__EXPORT__', (args) => handleExport(args, this.conversationHistory, this.agentProxy?.getCurrentModel())],
|
|
241
262
|
['__EXPORT_LIST__', () => handleExportList()],
|
|
242
263
|
['__EXPORT_FORMATS__', () => handleExportFormats()],
|
|
243
264
|
// Testing (context-dependent: codebuddyClient)
|
|
@@ -306,10 +327,11 @@ export class EnhancedCommandHandler {
|
|
|
306
327
|
['__BATCH__', (args) => handleBatchSlashCommand(args, this.createBatchChatFn(), this.createBatchSpawnFn())],
|
|
307
328
|
// Commands previously handled inline in client-dispatcher
|
|
308
329
|
['__CLEAR_CHAT__', () => handleClearChat()],
|
|
309
|
-
['__CHANGE_MODEL__', (args) => handleChangeModel(args)],
|
|
330
|
+
['__CHANGE_MODEL__', (args) => handleChangeModel(args, this.agentProxy?.getCurrentModel())],
|
|
310
331
|
['__CHANGE_MODE__', (args) => handleChangeMode(args)],
|
|
311
332
|
['__PLAN_MODE__', () => handleChangeMode(['plan'])],
|
|
312
|
-
['__STATUS__', () => handleStatus()],
|
|
333
|
+
['__STATUS__', () => handleStatus(this.agentProxy?.getCurrentModel())],
|
|
334
|
+
['__RESOURCES__', () => handleResources()],
|
|
313
335
|
['__NEW__', (args) => handleNew(args)],
|
|
314
336
|
['__ULTRAPLAN__', (args) => handleUltraplan(args)],
|
|
315
337
|
['__LIST_CHECKPOINTS__', (args) => handleListCheckpoints(args)],
|
|
@@ -541,7 +563,7 @@ export class EnhancedCommandHandler {
|
|
|
541
563
|
async handleCommand(token, args, _fullInput) {
|
|
542
564
|
const handler = this.handlerMap.get(token);
|
|
543
565
|
if (handler) {
|
|
544
|
-
return handler(args);
|
|
566
|
+
return withFactsMemorySessionClient(this.codebuddyClient ?? null, async () => normalizeHandlerResult(await handler(args)));
|
|
545
567
|
}
|
|
546
568
|
return { handled: false };
|
|
547
569
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Agent command handlers
|
|
3
3
|
*
|
|
4
4
|
* Handles /agent commands for custom agent management:
|
|
5
|
-
* - /agent - List all agents
|
|
5
|
+
* - /agent, /agent list - List all agents
|
|
6
6
|
* - /agent <id> - Activate an agent
|
|
7
7
|
* - /agent create <name> - Create a new agent
|
|
8
8
|
* - /agent info <id> - Show agent details
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Agent command handlers
|
|
3
3
|
*
|
|
4
4
|
* Handles /agent commands for custom agent management:
|
|
5
|
-
* - /agent - List all agents
|
|
5
|
+
* - /agent, /agent list - List all agents
|
|
6
6
|
* - /agent <id> - Activate an agent
|
|
7
7
|
* - /agent create <name> - Create a new agent
|
|
8
8
|
* - /agent info <id> - Show agent details
|
|
@@ -14,14 +14,14 @@ import { setActiveCustomAgentRuntime } from '../../agent/custom/custom-agent-run
|
|
|
14
14
|
*/
|
|
15
15
|
export function handleAgent(args) {
|
|
16
16
|
const loader = getCustomAgentLoader();
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const subcommand = args[0]?.toLowerCase() ?? '';
|
|
18
|
+
// No args or the documented `list` action - list agents
|
|
19
|
+
if (args.length === 0 || (subcommand === 'list' && args.length === 1)) {
|
|
19
20
|
return {
|
|
20
21
|
handled: true,
|
|
21
22
|
output: loader.formatAgentList(),
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
|
-
const subcommand = args[0]?.toLowerCase() ?? '';
|
|
25
25
|
// Create new agent
|
|
26
26
|
if (subcommand === 'create') {
|
|
27
27
|
return handleAgentCreate(args.slice(1));
|
|
@@ -1595,6 +1595,8 @@ export async function registerAIMessageHandler(manager) {
|
|
|
1595
1595
|
let successfulLisaSelfieToolResult = false;
|
|
1596
1596
|
let shouldPersistChannelSession = Boolean(agent);
|
|
1597
1597
|
let telegramWidget;
|
|
1598
|
+
let companionMediaResult;
|
|
1599
|
+
let companionHistorySuffix;
|
|
1598
1600
|
if (prefetchedDirectResponse) {
|
|
1599
1601
|
response = prefetchedDirectResponse;
|
|
1600
1602
|
if (agent && !agent.recordTrustedExternalConversationTurn(agentInput, response)) {
|
|
@@ -1632,16 +1634,34 @@ export async function registerAIMessageHandler(manager) {
|
|
|
1632
1634
|
sharedPhotos: companionPhotos?.photos.length ?? 0,
|
|
1633
1635
|
});
|
|
1634
1636
|
try {
|
|
1637
|
+
let companionIdentity;
|
|
1638
|
+
if (channel.type === 'telegram') {
|
|
1639
|
+
const { resolveCompanionIdentity } = await import('../../companion/companion-identity.js');
|
|
1640
|
+
const telegramChannel = channel;
|
|
1641
|
+
companionIdentity = resolveCompanionIdentity({
|
|
1642
|
+
channel: 'telegram',
|
|
1643
|
+
chatId: message.channel.id,
|
|
1644
|
+
senderId: message.sender?.id,
|
|
1645
|
+
senderUsername: message.sender?.username,
|
|
1646
|
+
allowedUsers: telegramChannel.config?.allowedUsers ?? [],
|
|
1647
|
+
env: process.env,
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1635
1650
|
const generated = await runCompanionChannelTurn({
|
|
1636
1651
|
apiKey: effectiveRuntime.apiKey,
|
|
1637
1652
|
baseUrl: effectiveRuntime.baseUrl,
|
|
1638
1653
|
model: effectiveRuntime.model,
|
|
1639
1654
|
messages: companionMessages,
|
|
1640
1655
|
signal: turn.signal,
|
|
1656
|
+
...(companionIdentity ? { identity: companionIdentity } : {}),
|
|
1657
|
+
surface: channel.type,
|
|
1658
|
+
env: process.env,
|
|
1641
1659
|
});
|
|
1642
1660
|
turn.throwIfAborted();
|
|
1643
1661
|
response = generated.text;
|
|
1644
1662
|
hasGeneratedResponse = response.trim() !== '';
|
|
1663
|
+
companionMediaResult = generated.media;
|
|
1664
|
+
companionHistorySuffix = generated.historySuffix;
|
|
1645
1665
|
if (hasSharedPhotos && companionPhotos) {
|
|
1646
1666
|
// The album write is deliberately after the reply: a full disk must
|
|
1647
1667
|
// cost the memory, never the reaction.
|
|
@@ -1860,7 +1880,35 @@ export async function registerAIMessageHandler(manager) {
|
|
|
1860
1880
|
turn.throwIfAborted();
|
|
1861
1881
|
turn.phase('delivery');
|
|
1862
1882
|
deliveryState = 'started';
|
|
1863
|
-
if (channel.type === 'telegram' && response.trim() &&
|
|
1883
|
+
if (channel.type === 'telegram' && response.trim() && companionMediaResult && companionMediaResult.length > 0) {
|
|
1884
|
+
const media = companionMediaResult[0];
|
|
1885
|
+
if (media) {
|
|
1886
|
+
const pathMod = await import('path');
|
|
1887
|
+
const ext = pathMod.extname(media.imagePath).slice(1) || 'png';
|
|
1888
|
+
const result = await channel.send({
|
|
1889
|
+
channelId: message.channel.id,
|
|
1890
|
+
content: response,
|
|
1891
|
+
replyTo: message.id,
|
|
1892
|
+
attachments: [
|
|
1893
|
+
{
|
|
1894
|
+
type: 'image',
|
|
1895
|
+
filePath: media.imagePath,
|
|
1896
|
+
fileName: pathMod.basename(media.imagePath),
|
|
1897
|
+
mimeType: ext === 'jpg' || ext === 'jpeg' ? 'image/jpeg' : `image/${ext}`,
|
|
1898
|
+
},
|
|
1899
|
+
],
|
|
1900
|
+
});
|
|
1901
|
+
delivered = result?.success === true;
|
|
1902
|
+
deliveredChunks = delivered ? 1 : 0;
|
|
1903
|
+
if (delivered)
|
|
1904
|
+
deliveredAssistantContent = response;
|
|
1905
|
+
if (delivered)
|
|
1906
|
+
deliveryMode = 'telegram-photo';
|
|
1907
|
+
else
|
|
1908
|
+
deliveryMode = 'failed';
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
else if (channel.type === 'telegram' && response.trim() && telegramWidget) {
|
|
1864
1912
|
const result = await channel.send({
|
|
1865
1913
|
channelId: message.channel.id,
|
|
1866
1914
|
content: response,
|
|
@@ -2070,7 +2118,10 @@ export async function registerAIMessageHandler(manager) {
|
|
|
2070
2118
|
turn.throwIfAborted();
|
|
2071
2119
|
turn.phase('persistence');
|
|
2072
2120
|
if (useCompanionProfile && response.trim()) {
|
|
2073
|
-
|
|
2121
|
+
const recordedResponse = companionHistorySuffix
|
|
2122
|
+
? `${response}${companionHistorySuffix}`
|
|
2123
|
+
: response;
|
|
2124
|
+
rememberCompanionChannelTurn(sessionKey, message.content, recordedResponse);
|
|
2074
2125
|
}
|
|
2075
2126
|
if (shouldPersistChannelSession && agent)
|
|
2076
2127
|
await persistChannelSession(agent, sessionKey);
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handlers for exporting sessions, conversations, and tool results
|
|
5
5
|
*/
|
|
6
|
+
import type { ChatEntry } from '../../agent/types.js';
|
|
6
7
|
import { CommandHandlerResult } from './branch-handlers.js';
|
|
7
8
|
/**
|
|
8
9
|
* Handle /export command
|
|
9
|
-
* Export current or
|
|
10
|
+
* Export the current conversation, or a saved session with session:<id>
|
|
10
11
|
*/
|
|
11
|
-
export declare function handleExport(args: string[]): Promise<CommandHandlerResult>;
|
|
12
|
+
export declare function handleExport(args: string[], conversationHistory?: ChatEntry[], currentModel?: string): Promise<CommandHandlerResult>;
|
|
12
13
|
/**
|
|
13
14
|
* Handle /export-list command
|
|
14
15
|
* List all exported files
|
|
@@ -3,54 +3,81 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handlers for exporting sessions, conversations, and tool results
|
|
5
5
|
*/
|
|
6
|
+
import { initializeDatabase } from '../../database/database-manager.js';
|
|
6
7
|
import { getExportManager } from '../../utils/export-manager.js';
|
|
7
|
-
|
|
8
|
+
function reply(content) {
|
|
9
|
+
return { handled: true, entry: { type: 'assistant', content, timestamp: new Date() } };
|
|
10
|
+
}
|
|
11
|
+
/** Map the visible transcript to export messages; UI-only entries are skipped. */
|
|
12
|
+
function chatEntriesToMessages(history) {
|
|
13
|
+
const messages = [];
|
|
14
|
+
for (const entry of history) {
|
|
15
|
+
if (entry.type === 'user' || entry.type === 'assistant') {
|
|
16
|
+
messages.push({ role: entry.type, content: entry.content, timestamp: entry.timestamp });
|
|
17
|
+
}
|
|
18
|
+
else if (entry.type === 'tool_result') {
|
|
19
|
+
messages.push({
|
|
20
|
+
role: 'tool',
|
|
21
|
+
content: entry.content,
|
|
22
|
+
timestamp: entry.timestamp,
|
|
23
|
+
toolName: entry.toolCall?.function?.name ?? 'tool',
|
|
24
|
+
toolCallId: entry.toolCall?.id,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return messages;
|
|
29
|
+
}
|
|
8
30
|
/**
|
|
9
31
|
* Handle /export command
|
|
10
|
-
* Export current or
|
|
32
|
+
* Export the current conversation, or a saved session with session:<id>
|
|
11
33
|
*/
|
|
12
|
-
export async function handleExport(args) {
|
|
34
|
+
export async function handleExport(args, conversationHistory = [], currentModel) {
|
|
13
35
|
const exportManager = getExportManager();
|
|
14
|
-
const sessionRepo = getSessionRepository();
|
|
15
36
|
// Parse arguments
|
|
16
37
|
const format = args.find(a => ['json', 'markdown', 'html', 'text'].includes(a)) || 'markdown';
|
|
17
38
|
const sessionIdArg = args.find(a => a.startsWith('session:'))?.split(':')[1];
|
|
18
39
|
const includeSecrets = args.includes('--include-secrets');
|
|
19
40
|
const noToolCalls = args.includes('--no-tools');
|
|
20
41
|
const noMetadata = args.includes('--no-metadata');
|
|
21
|
-
|
|
22
|
-
|
|
42
|
+
const options = {
|
|
43
|
+
redactSecrets: !includeSecrets,
|
|
44
|
+
includeToolCalls: !noToolCalls,
|
|
45
|
+
includeMetadata: !noMetadata,
|
|
46
|
+
};
|
|
47
|
+
let result;
|
|
23
48
|
if (sessionIdArg) {
|
|
24
|
-
|
|
49
|
+
// Saved sessions live in the SQLite session database, which the
|
|
50
|
+
// interactive CLI does not open at startup.
|
|
51
|
+
try {
|
|
52
|
+
await initializeDatabase();
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
return reply(`Failed to export session ${sessionIdArg}: session database unavailable (${error instanceof Error ? error.message : String(error)}).`);
|
|
56
|
+
}
|
|
57
|
+
result = await exportManager.exportSession(sessionIdArg, format, options);
|
|
25
58
|
}
|
|
26
59
|
else {
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
if (
|
|
31
|
-
return
|
|
32
|
-
handled: true,
|
|
33
|
-
entry: {
|
|
34
|
-
type: 'assistant',
|
|
35
|
-
content: 'No sessions found to export.',
|
|
36
|
-
timestamp: new Date(),
|
|
37
|
-
},
|
|
38
|
-
};
|
|
60
|
+
// The current session is the conversation on screen, not the most recent
|
|
61
|
+
// database row (which may belong to another project).
|
|
62
|
+
const messages = chatEntriesToMessages(conversationHistory);
|
|
63
|
+
if (messages.length === 0) {
|
|
64
|
+
return reply('Nothing to export yet: the current conversation is empty.\n\nSend a message first, or export a saved session with /export <format> session:<id>.');
|
|
39
65
|
}
|
|
40
|
-
|
|
66
|
+
result = await exportManager.exportConversationData({
|
|
67
|
+
title: 'Code Buddy conversation',
|
|
68
|
+
model: currentModel,
|
|
69
|
+
startTime: messages[0]?.timestamp,
|
|
70
|
+
endTime: messages[messages.length - 1]?.timestamp,
|
|
71
|
+
messages,
|
|
72
|
+
metadata: { projectPath: process.cwd(), messageCount: messages.length },
|
|
73
|
+
}, format, options);
|
|
41
74
|
}
|
|
42
|
-
// Export session
|
|
43
|
-
const result = await exportManager.exportSession(sessionId, format, {
|
|
44
|
-
redactSecrets: !includeSecrets,
|
|
45
|
-
includeToolCalls: !noToolCalls,
|
|
46
|
-
includeMetadata: !noMetadata,
|
|
47
|
-
});
|
|
48
75
|
if (result.success && result.filePath) {
|
|
49
76
|
return {
|
|
50
77
|
handled: true,
|
|
51
78
|
entry: {
|
|
52
79
|
type: 'assistant',
|
|
53
|
-
content: `Session exported successfully!
|
|
80
|
+
content: `${sessionIdArg ? `Session ${sessionIdArg}` : 'Current conversation'} exported successfully!
|
|
54
81
|
|
|
55
82
|
**Format:** ${format}
|
|
56
83
|
**File:** ${result.filePath}
|
|
@@ -68,7 +95,7 @@ cat "${result.filePath}"
|
|
|
68
95
|
handled: true,
|
|
69
96
|
entry: {
|
|
70
97
|
type: 'assistant',
|
|
71
|
-
content: `Failed to export session: ${result.error}`,
|
|
98
|
+
content: `Failed to export ${sessionIdArg ? `session ${sessionIdArg}` : 'the current conversation'}: ${result.error}`,
|
|
72
99
|
timestamp: new Date(),
|
|
73
100
|
},
|
|
74
101
|
};
|
|
@@ -311,7 +311,10 @@ export async function handleSearch(args) {
|
|
|
311
311
|
try {
|
|
312
312
|
const cwd = process.cwd();
|
|
313
313
|
let output = '';
|
|
314
|
-
|
|
314
|
+
// Explicit `.` path: without one, ripgrep searches stdin whenever stdin is
|
|
315
|
+
// not a TTY (every non-interactive spawn), so real matches were reported as
|
|
316
|
+
// "No matches" (status 1).
|
|
317
|
+
const rgResult = runCommand('rg', ['--line-number', '--no-heading', '--color=never', '--max-count=20', '--', query, '.'], { cwd, timeoutMs: 10000 });
|
|
315
318
|
if (rgResult.success) {
|
|
316
319
|
output = rgResult.output;
|
|
317
320
|
}
|
|
@@ -586,6 +589,7 @@ function createProgressBar(percent, width) {
|
|
|
586
589
|
function runCommand(command, args, { cwd, timeoutMs, env }) {
|
|
587
590
|
const result = spawnSync(command, args, {
|
|
588
591
|
cwd,
|
|
592
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
589
593
|
encoding: 'utf-8',
|
|
590
594
|
maxBuffer: 5 * 1024 * 1024,
|
|
591
595
|
timeout: timeoutMs,
|
|
@@ -1,32 +1,40 @@
|
|
|
1
|
+
// Written as the user's own request about their own work. The previous wording
|
|
2
|
+
// (role orders addressed to the assistant: "Mène un interrogatoire", "Exige",
|
|
3
|
+
// "Ne flatte pas l'auteur", "ce qui ment") made qwen3:4b answer the injection
|
|
4
|
+
// refusal sentence in the real CLI (recette 2026-09-14), without any tool call.
|
|
1
5
|
function buildPrompt(target, yolo) {
|
|
2
6
|
const scope = target
|
|
3
|
-
? `Sujet ciblé
|
|
4
|
-
: 'Sujet par défaut :
|
|
7
|
+
? `Sujet ciblé : ${target}`
|
|
8
|
+
: 'Sujet par défaut : mon travail récent dans ce dépôt.';
|
|
9
|
+
// The recent work includes uncommitted changes, and HEAD~1 does not exist in
|
|
10
|
+
// a single-commit repository: inspect the working tree first.
|
|
11
|
+
const gitInspection = 'git status --short, git diff (modifications non indexées), git diff --cached (modifications indexées) et git log -5 --oneline ; git diff HEAD~1 seulement si le dépôt compte au moins deux commits';
|
|
5
12
|
const baseInstructions = target
|
|
6
|
-
? `Examine d'abord ce sujet
|
|
7
|
-
:
|
|
13
|
+
? `Examine d'abord ce sujet avec les outils disponibles : ${target}. Utilise aussi le contexte git utile et la liste des fichiers modifiés : ${gitInspection}.`
|
|
14
|
+
: `Examine d'abord mon travail récent et la liste des fichiers modifiés avec les outils disponibles : ${gitInspection}.`;
|
|
8
15
|
if (yolo) {
|
|
9
|
-
return
|
|
16
|
+
return `J'ai lancé /grill-me --yolo : je veux une revue technique de mon propre travail en mode ROAST intégral.
|
|
17
|
+
|
|
18
|
+
${scope}
|
|
10
19
|
|
|
11
20
|
${baseInstructions}
|
|
12
21
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
Si une critique n'est pas étayée par le dépôt ou le diff, ne la formule pas.`;
|
|
22
|
+
Ensuite, sois brutal et sarcastique avec moi, sans politesse ni précautions diplomatiques.
|
|
23
|
+
Chaque critique doit rester techniquement exacte, vérifiable et actionnable : cite les fichiers, diffs, noms, tests ou choix qui la justifient.
|
|
24
|
+
Vise mes choix discutables, la dette introduite, les tests manquants, les cas limites ignorés, la sécurité, les abstractions inutiles et les noms trompeurs.
|
|
25
|
+
Pour chaque critique, demande-moi quelle preuve, quel test ou quel correctif fermera le sujet.
|
|
26
|
+
N'invente rien : une critique que le dépôt ou le diff ne prouve pas ne doit pas être formulée.`;
|
|
19
27
|
}
|
|
20
|
-
return
|
|
28
|
+
return `J'ai lancé /grill-me : je veux une revue technique exigeante de mon propre travail.
|
|
29
|
+
|
|
30
|
+
${scope}
|
|
21
31
|
|
|
22
32
|
${baseInstructions}
|
|
23
33
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
Ajoute ensuite 3 risques classés par sévérité, avec pour chacun l'impact, la probabilité et l'action minimale pour le réduire.
|
|
29
|
-
Ne flatte pas l'auteur : aide-le à voir ce qui casse, ce qui ment et ce qui manque.`;
|
|
34
|
+
Ensuite, pose-moi 5 à 7 questions difficiles et précises sur mes choix discutables, la dette introduite, les tests manquants, les cas limites ignorés, la sécurité et les noms trompeurs.
|
|
35
|
+
Chaque question doit viser des lignes, fichiers, comportements ou décisions observables, pas des généralités, et me demander une preuve concrète.
|
|
36
|
+
Termine par 3 risques classés par sévérité, avec pour chacun l'impact, la probabilité et l'action minimale pour le réduire.
|
|
37
|
+
Reste franc et constructif, sans compliments inutiles : aide-moi à voir ce qui casse, ce qui est inexact et ce qui manque.`;
|
|
30
38
|
}
|
|
31
39
|
export async function handleGrillMe(args) {
|
|
32
40
|
const remainingArgs = args.filter(arg => arg !== '--yolo');
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { ChatEntry } from "../../agent/codebuddy-agent.js";
|
|
2
|
+
export interface MemoryCommandContext {
|
|
3
|
+
cwd?: string;
|
|
4
|
+
botId?: string;
|
|
5
|
+
}
|
|
2
6
|
export interface CommandHandlerResult {
|
|
3
7
|
handled: boolean;
|
|
4
8
|
entry?: ChatEntry;
|
|
@@ -9,11 +13,11 @@ export interface CommandHandlerResult {
|
|
|
9
13
|
/**
|
|
10
14
|
* Memory - Manage persistent memory using PersistentMemoryManager (Markdown) and EnhancedMemory (SQLite/Vector)
|
|
11
15
|
*/
|
|
12
|
-
export declare function handleMemory(args: string[]): Promise<CommandHandlerResult>;
|
|
16
|
+
export declare function handleMemory(args: string[], context?: MemoryCommandContext): Promise<CommandHandlerResult>;
|
|
13
17
|
/**
|
|
14
18
|
* Remember - Quick memory store using PersistentMemoryManager and EnhancedMemory
|
|
15
19
|
*/
|
|
16
|
-
export declare function handleRemember(args: string[]): Promise<CommandHandlerResult>;
|
|
20
|
+
export declare function handleRemember(args: string[], context?: MemoryCommandContext): Promise<CommandHandlerResult>;
|
|
17
21
|
/**
|
|
18
22
|
* Scan Todos - Find AI-directed comments
|
|
19
23
|
*/
|