@xopcai/xopc 0.0.123 → 0.0.124
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.md +28 -11
- package/README.zh-CN.md +28 -11
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Bicr3ZBg.js → agent-avatar-dicebear-B5uSVAyJ.js} +1 -1
- package/dist/gateway/static/root/assets/agents-BjIxt67Z.js +2 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-CbEy9sR1.js → app-management-settings-panel-CYCONLIL.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CTHja6n9.js → appearance-settings-Clw3ryKg.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-QICTeGjX.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-Bpy64GjU.js → archive-plugin-CXUGRp2i.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DMkp4xSb.js → attachment-load-Cmiub3Wg.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-KnYaP7NT.js → automation-suggestion-card-CU0-4nQ-.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-Car-jtiz.js +1 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DA9C5mCw.js → binary-plugins-0Izz-N3p.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CiSXk_YC.js → block-editor-C1Kv0IkJ.js} +6 -6
- package/dist/gateway/static/root/assets/browser-settings-page-CMeBJzlS.js +8 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-CEJ44WCU.js → capability-presets-api-BmQTM9Il.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DZEJEoCF.js +1 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-CDhrhfhN.js → channel-recipient-api-BeA2aVor.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-kkW-xFau.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-BvaQvO5F.js +2 -0
- package/dist/gateway/static/root/assets/{directory-picker-path-field-7jKfbH0J.js → directory-picker-path-field-2rjzUu57.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-m1-wmz4o.js → dreaming-settings-DnHO686d.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-C9qQQrBS.js → extension-debug-page-BGLRuWVN.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DcBBMEGl.js → extension-page-D978ePp9.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BQ-jMMP9.js → extension-settings-page-B6Ih4Swx.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-Dtpbbe0s.js → fetch-BU5S0Sn7.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-BN6pyX2c.js → gateway-config-api-BIPGwrl1.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-CMEA3r5u.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-BIET2x3y.js → gateway-startup-retry-Cd0Zz30N.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-create-dialog-BuIMDx6C.js → goal-create-dialog-B-KHKeXN.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-BxrSoWdj.js +1 -0
- package/dist/gateway/static/root/assets/{goals-config-api-CQm2r1Ty.js → goals-config-api-B95KdGMj.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-BTJzIl28.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-DDrdRMxB.js → goals-settings-BJyEuLLm.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-wkOjYNQT.js +1 -0
- package/dist/gateway/static/root/assets/{index-CBDr5xjB.css → index-BLaXr6Ev.css} +1 -1
- package/dist/gateway/static/root/assets/index-c_9TVr_C.js +191 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-C2TuQppb.js → keyboard-shortcuts-settings-BT8T4DyC.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-CrxBJUgI.js +2 -0
- package/dist/gateway/static/root/assets/{markdown-split-DhONQ81k.js → markdown-split-Dv66bO2b.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DS44pJzr.js → media-plugins-BhIQU5yS.js} +1 -1
- package/dist/gateway/static/root/assets/messages-O6TAtdFC.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-DOOpz6y1.js +2 -0
- package/dist/gateway/static/root/assets/notes-page-Br16pK9v.js +1 -0
- package/dist/gateway/static/root/assets/notes-workbench-PSJAi0ZC.js +2 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Dej6zHnr.js → preview-open-alternatives-DGzet1d7.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-CIGGgKuw.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-B2grhsBt.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-CXMORxBD.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-Zu1FzH6z.js → save-bar-controls-Cqgb-jqa.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-BW78mKc0.js → schedule-field-DVZcI8Yt.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-Cc-IOydE.js → schema-form-Bj7sOxC8.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-Bi2wkBzU.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-B1L3G4IA.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-DIpIYht_.js → settings-collapsible-section-BmXn-8N6.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-BFxBNxOG.js → settings-form-section-BnqYMWHR.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-BfRSHJmO.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-layout-CLx4o2PN.js → settings-page-layout-CdWZU1hd.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CWtPM7RK.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-ZswWCrDu.js → share-preview-page-IB1v8i86.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-ngbsBgij.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BIe442Gv.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-BfchZRVa.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-3ZNcGRhS.js → system-settings-panel-BxQ384RC.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-bpzZjiVF.js → typed-models-lib-BkcpvFYO.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-BCjZLZ3O.js → use-channel-catalog-Cd0FaEQ4.js} +1 -1
- package/dist/gateway/static/root/assets/{user-profile-settings-panel-CIXafITi.js → user-profile-settings-panel-DQ7NnRSY.js} +1 -1
- package/dist/gateway/static/root/assets/{utils-DXMtz5j_.js → utils-YKhVf7Ka.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-C5Ov8Uk_.js +1 -0
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-BYD9BtOq.js +3 -0
- package/dist/gateway/static/root/assets/{workflow-start-dialog-B4sZpTDQ.js → workflow-start-dialog-BNJVCWoS.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-BYF29ANm.js +18 -0
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +6 -1
- package/dist/src/agent/agent-manager.js +28 -12
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
- package/dist/src/agent/embedded/xopc-tools-bridge.js +11 -7
- package/dist/src/agent/embedded/xopc-tools-bridge.js.map +1 -1
- package/dist/src/agent/lifecycle/progress.js +3 -1
- package/dist/src/agent/lifecycle/progress.js.map +1 -1
- package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +2 -2
- package/dist/src/agent/lifecycle/timeout-wrapper.js +4 -4
- package/dist/src/agent/lifecycle/timeout-wrapper.js.map +1 -1
- package/dist/src/agent/memory/summary-generator.d.ts +1 -1
- package/dist/src/agent/memory/summary-generator.js +1 -2
- package/dist/src/agent/memory/summary-generator.js.map +1 -1
- package/dist/src/agent/middleware/index.d.ts +1 -1
- package/dist/src/agent/middleware/self-verify.d.ts +44 -14
- package/dist/src/agent/middleware/self-verify.js +214 -44
- package/dist/src/agent/middleware/self-verify.js.map +1 -1
- package/dist/src/agent/orchestration/agent-event-handler.js +57 -15
- package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
- package/dist/src/agent/prompt/sections/tooling.js +18 -13
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
- package/dist/src/agent/prompt/system-reminder.js +2 -2
- package/dist/src/agent/prompt/system-reminder.js.map +1 -1
- package/dist/src/agent/sandbox/sanitize-env-vars.d.ts +2 -2
- package/dist/src/agent/sandbox/sanitize-env-vars.js +2 -2
- package/dist/src/agent/sandbox/sanitize-env-vars.js.map +1 -1
- package/dist/src/agent/sandbox/types.d.ts +2 -2
- package/dist/src/agent/sandbox/types.js.map +1 -1
- package/dist/src/agent/service/btw-query.js +1 -1
- package/dist/src/agent/service/btw-query.js.map +1 -1
- package/dist/src/agent/service/process-direct-one-shot.js +6 -2
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +12 -7
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service.js +2 -1
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/skills/skill-tool-gating.js +1 -1
- package/dist/src/agent/skills/skill-tool-gating.js.map +1 -1
- package/dist/src/agent/starter-agents.js +9 -9
- package/dist/src/agent/starter-agents.js.map +1 -1
- package/dist/src/agent/tools/apply-patch.d.ts +25 -0
- package/dist/src/agent/tools/apply-patch.js +256 -0
- package/dist/src/agent/tools/apply-patch.js.map +1 -0
- package/dist/src/agent/tools/delegate-tool.d.ts +1 -1
- package/dist/src/agent/tools/delegate-tool.js +3 -3
- package/dist/src/agent/tools/delegate-tool.js.map +1 -1
- package/dist/src/agent/tools/exec-command.d.ts +30 -0
- package/dist/src/agent/tools/exec-command.js +224 -0
- package/dist/src/agent/tools/exec-command.js.map +1 -0
- package/dist/src/agent/tools/execute-code-tool.js +7 -4
- package/dist/src/agent/tools/execute-code-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.d.ts +3 -3
- package/dist/src/agent/tools/factory.js +7 -8
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/index.d.ts +3 -2
- package/dist/src/agent/tools/index.js +5 -4
- package/dist/src/agent/tools/skills-tools.d.ts +1 -1
- package/dist/src/agent/tools/skills-tools.js.map +1 -1
- package/dist/src/agent/tools/update-plan-tool.d.ts +11 -0
- package/dist/src/agent/tools/update-plan-tool.js +72 -0
- package/dist/src/agent/tools/update-plan-tool.js.map +1 -0
- package/dist/src/agent/workflow/builtins/debug-incident.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/debug-incident.js +1 -1
- package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.js +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
- package/dist/src/agent/workflow/builtins/release-check.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/release-check.js +1 -1
- package/dist/src/agent/workflow/builtins/release-check.js.map +1 -1
- package/dist/src/agent/workflow/step-labels.js +7 -3
- package/dist/src/agent/workflow/step-labels.js.map +1 -1
- package/dist/src/chat-commands/agent-edit.js +1 -1
- package/dist/src/chat-commands/agent-edit.js.map +1 -1
- package/dist/src/chat-commands/builtins/review.d.ts +1 -0
- package/dist/src/chat-commands/builtins/review.js +167 -0
- package/dist/src/chat-commands/builtins/review.js.map +1 -0
- package/dist/src/chat-commands/index.d.ts +1 -0
- package/dist/src/chat-commands/index.js +3 -1
- package/dist/src/chat-commands/index.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agent-builtin-tools.js +3 -2
- package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
- package/dist/src/gateway/chat-stream/mapper.d.ts +6 -0
- package/dist/src/gateway/chat-stream/mapper.js +149 -6
- package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
- package/dist/src/gateway/chat-stream/protocol.d.ts +51 -1
- package/dist/src/gateway/hono/routes/commands-skills.js +21 -0
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/index.js +2 -0
- package/dist/src/gateway/hono/routes/index.js.map +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +1 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/projects.js +40 -2
- package/dist/src/gateway/hono/routes/projects.js.map +1 -1
- package/dist/src/gateway/hono/routes/search.d.ts +3 -0
- package/dist/src/gateway/hono/routes/search.js +47 -0
- package/dist/src/gateway/hono/routes/search.js.map +1 -0
- package/dist/src/gateway/security/dangerous-tools.js +1 -1
- package/dist/src/gateway/security/dangerous-tools.js.map +1 -1
- package/dist/src/infra/update-restart.js +1 -1
- package/dist/src/mcp/channel-bridge.js +1 -1
- package/dist/src/projects/index.d.ts +2 -0
- package/dist/src/projects/index.js +3 -1
- package/dist/src/projects/project-agent-suggestion.d.ts +14 -0
- package/dist/src/projects/project-agent-suggestion.js +19 -0
- package/dist/src/projects/project-agent-suggestion.js.map +1 -0
- package/dist/src/projects/project-kind.d.ts +13 -0
- package/dist/src/projects/project-kind.js +147 -0
- package/dist/src/projects/project-kind.js.map +1 -0
- package/dist/src/projects/project-service.d.ts +1 -0
- package/dist/src/projects/project-service.js +1 -1
- package/dist/src/projects/project-service.js.map +1 -1
- package/dist/src/projects/project-store.js +32 -8
- package/dist/src/projects/project-store.js.map +1 -1
- package/dist/src/projects/types.d.ts +1 -0
- package/dist/src/review/review-git.d.ts +48 -0
- package/dist/src/review/review-git.js +333 -0
- package/dist/src/review/review-git.js.map +1 -0
- package/dist/src/review/review-types.d.ts +22 -0
- package/dist/src/review/review-types.js +29 -0
- package/dist/src/review/review-types.js.map +1 -0
- package/dist/src/session/session-context-for-llm.js +151 -0
- package/dist/src/session/session-context-for-llm.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/021_projects_fts.sql +21 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/tui/backends/embedded-backend.d.ts +1 -0
- package/dist/src/tui/backends/embedded-backend.js +20 -0
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +2 -0
- package/dist/src/tui/backends/gateway-sse-backend.js +7 -0
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/components/assistant-message.js +35 -0
- package/dist/src/tui/components/assistant-message.js.map +1 -1
- package/dist/src/tui/tui-agent-events.js +25 -0
- package/dist/src/tui/tui-agent-events.js.map +1 -1
- package/dist/src/tui/tui-backend.d.ts +4 -0
- package/dist/src/tui/tui-commands.d.ts +1 -0
- package/dist/src/tui/tui-commands.js +110 -4
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-picker-overlay.d.ts +2 -0
- package/dist/src/tui/tui-picker-overlay.js +153 -1
- package/dist/src/tui/tui-picker-overlay.js.map +1 -1
- package/dist/src/tui/tui.js +16 -3
- package/dist/src/tui/tui.js.map +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agents-CxDSFHGx.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-CyZdgqvm.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-8VLKM4au.js +0 -1
- package/dist/gateway/static/root/assets/browser-settings-page-5tPg0DcP.js +0 -8
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-BJW3aVST.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-CorUCTrs.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-VKstC3sP.js +0 -2
- package/dist/gateway/static/root/assets/gateway-settings-hQtgVmSR.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-FEypCq74.js +0 -1
- package/dist/gateway/static/root/assets/goals-page-C4-2_MLG.js +0 -2
- package/dist/gateway/static/root/assets/heartbeat-settings-BJVok3Sl.js +0 -1
- package/dist/gateway/static/root/assets/index-T0SaNd5a.js +0 -191
- package/dist/gateway/static/root/assets/logs-page-DwkwPgid.js +0 -2
- package/dist/gateway/static/root/assets/messages-avfvyZuQ.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-huNY4A1G.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-DdfGuEZ1.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-B0bT9Hqa.js +0 -2
- package/dist/gateway/static/root/assets/project-detail-page-CjxhPorG.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-C4Z5OJMF.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CVCOPUVd.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-B4qExXHC.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-Ce8yLTBi.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-C4fivemT.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Kyc4eUf0.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-Bu76CMiC.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-D-CFg86j.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-CUU4f6Ss.js +0 -2
- package/dist/gateway/static/root/assets/voice-api-key-field-C1MrQD8R.js +0 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-DqizIcY5.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-B3sVNPFk.js +0 -18
- package/dist/src/agent/tools/edit.d.ts +0 -14
- package/dist/src/agent/tools/edit.js +0 -132
- package/dist/src/agent/tools/edit.js.map +0 -1
- package/dist/src/agent/tools/shell.d.ts +0 -15
- package/dist/src/agent/tools/shell.js +0 -158
- package/dist/src/agent/tools/shell.js.map +0 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { effectiveWorkspacePathForSession } from "../../session/session-workspace.js";
|
|
2
|
+
import { getProjectForSession } from "../../projects/workspace.js";
|
|
3
|
+
import { commandRegistry } from "../registry.js";
|
|
4
|
+
import { buildReviewDiffBundle, parseReviewTargetArgs, resolveGitRoot } from "../../review/review-git.js";
|
|
5
|
+
import { formatReviewMarkdown } from "../../review/review-types.js";
|
|
6
|
+
//#region src/chat-commands/builtins/review.ts
|
|
7
|
+
const MAX_DIFF_CHARS = 6e4;
|
|
8
|
+
function truncateForPrompt(text) {
|
|
9
|
+
if (text.length <= MAX_DIFF_CHARS) return {
|
|
10
|
+
text,
|
|
11
|
+
truncated: false
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
text: text.slice(0, MAX_DIFF_CHARS) + "\n\n[diff truncated]",
|
|
15
|
+
truncated: true
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function extractJsonObject(raw) {
|
|
19
|
+
const text = (raw.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1] ?? raw).trim();
|
|
20
|
+
const start = text.indexOf("{");
|
|
21
|
+
const end = text.lastIndexOf("}");
|
|
22
|
+
if (start < 0 || end <= start) throw new Error("review response did not contain JSON");
|
|
23
|
+
return JSON.parse(text.slice(start, end + 1));
|
|
24
|
+
}
|
|
25
|
+
function priorityFrom(raw) {
|
|
26
|
+
const n = typeof raw === "number" ? raw : Number.parseInt(String(raw ?? ""), 10);
|
|
27
|
+
if (n === 0 || n === 1 || n === 2 || n === 3) return n;
|
|
28
|
+
return 2;
|
|
29
|
+
}
|
|
30
|
+
function numberFrom(raw) {
|
|
31
|
+
return typeof raw === "number" && Number.isFinite(raw) ? raw : void 0;
|
|
32
|
+
}
|
|
33
|
+
function stringFrom(raw) {
|
|
34
|
+
return typeof raw === "string" ? raw.trim() : "";
|
|
35
|
+
}
|
|
36
|
+
function parseReviewJson(raw, target) {
|
|
37
|
+
const parsed = extractJsonObject(raw);
|
|
38
|
+
const rec = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
39
|
+
const findings = (Array.isArray(rec.findings) ? rec.findings : []).map((item) => {
|
|
40
|
+
const f = item && typeof item === "object" && !Array.isArray(item) ? item : {};
|
|
41
|
+
const loc = f.code_location && typeof f.code_location === "object" ? f.code_location : {};
|
|
42
|
+
const range = loc.line_range && typeof loc.line_range === "object" ? loc.line_range : {};
|
|
43
|
+
const title = stringFrom(f.title);
|
|
44
|
+
const body = stringFrom(f.body);
|
|
45
|
+
if (!title && !body) return void 0;
|
|
46
|
+
const finding = {
|
|
47
|
+
title: title || body.slice(0, 80),
|
|
48
|
+
body,
|
|
49
|
+
priority: priorityFrom(f.priority)
|
|
50
|
+
};
|
|
51
|
+
const confidenceScore = numberFrom(f.confidence_score ?? f.confidenceScore);
|
|
52
|
+
const filePath = stringFrom(loc.file_path ?? f.filePath);
|
|
53
|
+
const lineStart = numberFrom(range.start ?? f.lineStart);
|
|
54
|
+
const lineEnd = numberFrom(range.end ?? f.lineEnd);
|
|
55
|
+
if (confidenceScore !== void 0) finding.confidenceScore = confidenceScore;
|
|
56
|
+
if (filePath) finding.filePath = filePath;
|
|
57
|
+
if (lineStart !== void 0) finding.lineStart = lineStart;
|
|
58
|
+
if (lineEnd !== void 0) finding.lineEnd = lineEnd;
|
|
59
|
+
return finding;
|
|
60
|
+
}).filter((item) => Boolean(item));
|
|
61
|
+
const correctness = stringFrom(rec.overall_correctness ?? rec.overallCorrectness);
|
|
62
|
+
const overallCorrectness = correctness === "patch is correct" || correctness === "patch is incorrect" ? correctness : "unknown";
|
|
63
|
+
return {
|
|
64
|
+
type: "review",
|
|
65
|
+
target,
|
|
66
|
+
summary: stringFrom(rec.summary) || `${findings.length} finding${findings.length === 1 ? "" : "s"}`,
|
|
67
|
+
findings,
|
|
68
|
+
overallCorrectness,
|
|
69
|
+
overallExplanation: stringFrom(rec.overall_explanation ?? rec.overallExplanation),
|
|
70
|
+
overallConfidenceScore: numberFrom(rec.overall_confidence_score ?? rec.overallConfidenceScore),
|
|
71
|
+
generatedAt: Date.now(),
|
|
72
|
+
source: "model"
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function buildReviewPrompt(params) {
|
|
76
|
+
return [
|
|
77
|
+
"You are a senior code reviewer. Review the provided git diff for correctness bugs only.",
|
|
78
|
+
"Prioritize concrete regressions, broken behavior, missing required tests for changed behavior, data loss, security issues, and runtime/type errors.",
|
|
79
|
+
"Do not mention style, broad refactors, praise, or speculative improvements.",
|
|
80
|
+
"Return strict JSON only with this shape:",
|
|
81
|
+
"{\"findings\":[{\"title\":\"...\",\"body\":\"...\",\"priority\":1,\"confidence_score\":0.9,\"code_location\":{\"file_path\":\"path\",\"line_range\":{\"start\":12,\"end\":12}}}],\"overall_correctness\":\"patch is correct\",\"overall_explanation\":\"...\",\"overall_confidence_score\":0.8,\"summary\":\"...\"}",
|
|
82
|
+
"Use priority 0 for release-blocking, 1 for high, 2 for medium, 3 for low.",
|
|
83
|
+
params.instructions ? `Extra reviewer instructions: ${params.instructions}` : "",
|
|
84
|
+
`Target: ${params.target}`,
|
|
85
|
+
params.truncated ? "The diff was truncated; only report findings supported by visible lines." : "",
|
|
86
|
+
"Git status:",
|
|
87
|
+
params.status || "(clean)",
|
|
88
|
+
"Diff stat:",
|
|
89
|
+
params.stat || "(none)",
|
|
90
|
+
"Diff:",
|
|
91
|
+
params.diff || "(none)"
|
|
92
|
+
].filter(Boolean).join("\n\n");
|
|
93
|
+
}
|
|
94
|
+
async function resolveWorkspace(ctx) {
|
|
95
|
+
const sessionConfigStore = ctx.getSessionConfigStore?.();
|
|
96
|
+
const sessionConfig = sessionConfigStore ? await sessionConfigStore.get(ctx.sessionKey).catch(() => null) : null;
|
|
97
|
+
return effectiveWorkspacePathForSession(ctx.config, ctx.sessionKey, sessionConfig, getProjectForSession(ctx.sessionKey));
|
|
98
|
+
}
|
|
99
|
+
async function buildReview(ctx, args) {
|
|
100
|
+
const cwd = await resolveGitRoot(await resolveWorkspace(ctx));
|
|
101
|
+
const reviewTarget = parseReviewTargetArgs(args);
|
|
102
|
+
const bundle = await buildReviewDiffBundle(cwd, reviewTarget);
|
|
103
|
+
const { text: diff, truncated } = truncateForPrompt(bundle.diff);
|
|
104
|
+
const target = bundle.targetLabel;
|
|
105
|
+
const instructions = reviewTarget.instructions ?? "";
|
|
106
|
+
if (!bundle.status.trim() && !bundle.diff.trim()) return {
|
|
107
|
+
type: "review",
|
|
108
|
+
target,
|
|
109
|
+
summary: "Working tree is clean.",
|
|
110
|
+
findings: [],
|
|
111
|
+
overallCorrectness: "patch is correct",
|
|
112
|
+
overallExplanation: "No uncommitted changes were found to review.",
|
|
113
|
+
generatedAt: Date.now(),
|
|
114
|
+
source: "local"
|
|
115
|
+
};
|
|
116
|
+
const prompt = buildReviewPrompt({
|
|
117
|
+
target,
|
|
118
|
+
status: bundle.status,
|
|
119
|
+
stat: bundle.stat,
|
|
120
|
+
diff,
|
|
121
|
+
truncated,
|
|
122
|
+
instructions
|
|
123
|
+
});
|
|
124
|
+
const answer = await ctx.btwQuery?.(prompt);
|
|
125
|
+
if (answer?.text && !answer.error) try {
|
|
126
|
+
return parseReviewJson(answer.text, target);
|
|
127
|
+
} catch {}
|
|
128
|
+
return {
|
|
129
|
+
type: "review",
|
|
130
|
+
target,
|
|
131
|
+
summary: "Review model was unavailable; returned a local diff summary.",
|
|
132
|
+
findings: [],
|
|
133
|
+
overallCorrectness: "unknown",
|
|
134
|
+
overallExplanation: [answer?.error ? `Reviewer model error: ${answer.error}` : "Reviewer model output could not be parsed.", bundle.stat.trim() ? `Changed files:\n${bundle.stat.trim()}` : "No textual diff stat was available."].join("\n\n"),
|
|
135
|
+
generatedAt: Date.now(),
|
|
136
|
+
source: "local"
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
const reviewCommand = {
|
|
140
|
+
id: "coding.review",
|
|
141
|
+
name: "review",
|
|
142
|
+
description: "Review current workspace changes for correctness issues",
|
|
143
|
+
category: "tool",
|
|
144
|
+
scope: [
|
|
145
|
+
"global",
|
|
146
|
+
"private",
|
|
147
|
+
"group"
|
|
148
|
+
],
|
|
149
|
+
acceptsArgs: true,
|
|
150
|
+
examples: ["/review", "/review focus on auth and persistence"],
|
|
151
|
+
handler: async (ctx, args) => {
|
|
152
|
+
await ctx.setTyping(true);
|
|
153
|
+
const review = await buildReview(ctx, args);
|
|
154
|
+
return {
|
|
155
|
+
content: formatReviewMarkdown(review),
|
|
156
|
+
success: true,
|
|
157
|
+
metadata: { review }
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
function registerReviewCommand() {
|
|
162
|
+
commandRegistry.register(reviewCommand);
|
|
163
|
+
}
|
|
164
|
+
//#endregion
|
|
165
|
+
export { registerReviewCommand };
|
|
166
|
+
|
|
167
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","names":[],"sources":["../../../../src/chat-commands/builtins/review.ts"],"sourcesContent":["import type { CommandDefinition, CommandContext } from '../types.js';\nimport { commandRegistry } from '../registry.js';\nimport { effectiveWorkspacePathForSession } from '../../session/session-workspace.js';\nimport { getProjectForSession } from '../../projects/workspace.js';\nimport {\n buildReviewDiffBundle,\n parseReviewTargetArgs,\n resolveGitRoot,\n} from '../../review/review-git.js';\nimport {\n formatReviewMarkdown,\n type ReviewFinding,\n type ReviewOutput,\n type ReviewPriority,\n} from '../../review/review-types.js';\n\nconst MAX_DIFF_CHARS = 60_000;\n\nfunction truncateForPrompt(text: string): { text: string; truncated: boolean } {\n if (text.length <= MAX_DIFF_CHARS) return { text, truncated: false };\n return {\n text: text.slice(0, MAX_DIFF_CHARS) + '\\n\\n[diff truncated]',\n truncated: true,\n };\n}\n\nfunction extractJsonObject(raw: string): unknown {\n const fenced = raw.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n const text = (fenced?.[1] ?? raw).trim();\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start < 0 || end <= start) throw new Error('review response did not contain JSON');\n return JSON.parse(text.slice(start, end + 1));\n}\n\nfunction priorityFrom(raw: unknown): ReviewPriority {\n const n = typeof raw === 'number' ? raw : Number.parseInt(String(raw ?? ''), 10);\n if (n === 0 || n === 1 || n === 2 || n === 3) return n;\n return 2;\n}\n\nfunction numberFrom(raw: unknown): number | undefined {\n return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined;\n}\n\nfunction stringFrom(raw: unknown): string {\n return typeof raw === 'string' ? raw.trim() : '';\n}\n\nfunction parseReviewJson(raw: string, target: string): ReviewOutput {\n const parsed = extractJsonObject(raw);\n const rec = parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? parsed as Record<string, unknown>\n : {};\n const rawFindings = Array.isArray(rec.findings) ? rec.findings : [];\n const findings: ReviewFinding[] = rawFindings\n .map((item) => {\n const f = item && typeof item === 'object' && !Array.isArray(item)\n ? item as Record<string, unknown>\n : {};\n const loc = f.code_location && typeof f.code_location === 'object'\n ? f.code_location as Record<string, unknown>\n : {};\n const range = loc.line_range && typeof loc.line_range === 'object'\n ? loc.line_range as Record<string, unknown>\n : {};\n const title = stringFrom(f.title);\n const body = stringFrom(f.body);\n if (!title && !body) return undefined;\n const finding: ReviewFinding = {\n title: title || body.slice(0, 80),\n body,\n priority: priorityFrom(f.priority),\n };\n const confidenceScore = numberFrom(f.confidence_score ?? f.confidenceScore);\n const filePath = stringFrom(loc.file_path ?? f.filePath);\n const lineStart = numberFrom(range.start ?? f.lineStart);\n const lineEnd = numberFrom(range.end ?? f.lineEnd);\n if (confidenceScore !== undefined) finding.confidenceScore = confidenceScore;\n if (filePath) finding.filePath = filePath;\n if (lineStart !== undefined) finding.lineStart = lineStart;\n if (lineEnd !== undefined) finding.lineEnd = lineEnd;\n return finding;\n })\n .filter((item): item is ReviewFinding => Boolean(item));\n\n const correctness = stringFrom(rec.overall_correctness ?? rec.overallCorrectness);\n const overallCorrectness =\n correctness === 'patch is correct' || correctness === 'patch is incorrect'\n ? correctness\n : 'unknown';\n return {\n type: 'review',\n target,\n summary: stringFrom(rec.summary) || `${findings.length} finding${findings.length === 1 ? '' : 's'}`,\n findings,\n overallCorrectness,\n overallExplanation: stringFrom(rec.overall_explanation ?? rec.overallExplanation),\n overallConfidenceScore: numberFrom(rec.overall_confidence_score ?? rec.overallConfidenceScore),\n generatedAt: Date.now(),\n source: 'model',\n };\n}\n\nfunction buildReviewPrompt(params: {\n target: string;\n status: string;\n stat: string;\n diff: string;\n truncated: boolean;\n instructions: string;\n}): string {\n return [\n 'You are a senior code reviewer. Review the provided git diff for correctness bugs only.',\n 'Prioritize concrete regressions, broken behavior, missing required tests for changed behavior, data loss, security issues, and runtime/type errors.',\n 'Do not mention style, broad refactors, praise, or speculative improvements.',\n 'Return strict JSON only with this shape:',\n '{\"findings\":[{\"title\":\"...\",\"body\":\"...\",\"priority\":1,\"confidence_score\":0.9,\"code_location\":{\"file_path\":\"path\",\"line_range\":{\"start\":12,\"end\":12}}}],\"overall_correctness\":\"patch is correct\",\"overall_explanation\":\"...\",\"overall_confidence_score\":0.8,\"summary\":\"...\"}',\n 'Use priority 0 for release-blocking, 1 for high, 2 for medium, 3 for low.',\n params.instructions ? `Extra reviewer instructions: ${params.instructions}` : '',\n `Target: ${params.target}`,\n params.truncated ? 'The diff was truncated; only report findings supported by visible lines.' : '',\n 'Git status:',\n params.status || '(clean)',\n 'Diff stat:',\n params.stat || '(none)',\n 'Diff:',\n params.diff || '(none)',\n ].filter(Boolean).join('\\n\\n');\n}\n\nasync function resolveWorkspace(ctx: CommandContext): Promise<string> {\n const sessionConfigStore = ctx.getSessionConfigStore?.();\n const sessionConfig = sessionConfigStore\n ? await sessionConfigStore.get(ctx.sessionKey).catch(() => null)\n : null;\n return effectiveWorkspacePathForSession(\n ctx.config,\n ctx.sessionKey,\n sessionConfig,\n getProjectForSession(ctx.sessionKey),\n );\n}\n\nasync function buildReview(ctx: CommandContext, args: string): Promise<ReviewOutput> {\n const workspace = await resolveWorkspace(ctx);\n const cwd = await resolveGitRoot(workspace);\n const reviewTarget = parseReviewTargetArgs(args);\n const bundle = await buildReviewDiffBundle(cwd, reviewTarget);\n const { text: diff, truncated } = truncateForPrompt(bundle.diff);\n const target = bundle.targetLabel;\n const instructions = reviewTarget.instructions ?? '';\n\n if (!bundle.status.trim() && !bundle.diff.trim()) {\n return {\n type: 'review',\n target,\n summary: 'Working tree is clean.',\n findings: [],\n overallCorrectness: 'patch is correct',\n overallExplanation: 'No uncommitted changes were found to review.',\n generatedAt: Date.now(),\n source: 'local',\n };\n }\n\n const prompt = buildReviewPrompt({\n target,\n status: bundle.status,\n stat: bundle.stat,\n diff,\n truncated,\n instructions,\n });\n const answer = await ctx.btwQuery?.(prompt);\n if (answer?.text && !answer.error) {\n try {\n return parseReviewJson(answer.text, target);\n } catch {\n // Fall through to a deterministic local summary when model output is not parseable.\n }\n }\n\n return {\n type: 'review',\n target,\n summary: 'Review model was unavailable; returned a local diff summary.',\n findings: [],\n overallCorrectness: 'unknown',\n overallExplanation: [\n answer?.error ? `Reviewer model error: ${answer.error}` : 'Reviewer model output could not be parsed.',\n bundle.stat.trim() ? `Changed files:\\n${bundle.stat.trim()}` : 'No textual diff stat was available.',\n ].join('\\n\\n'),\n generatedAt: Date.now(),\n source: 'local',\n };\n}\n\nconst reviewCommand: CommandDefinition = {\n id: 'coding.review',\n name: 'review',\n description: 'Review current workspace changes for correctness issues',\n category: 'tool',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: ['/review', '/review focus on auth and persistence'],\n handler: async (ctx: CommandContext, args: string) => {\n await ctx.setTyping(true);\n const review = await buildReview(ctx, args);\n return {\n content: formatReviewMarkdown(review),\n success: true,\n metadata: { review },\n };\n },\n};\n\nexport function registerReviewCommand(): void {\n commandRegistry.register(reviewCommand);\n}\n"],"mappings":"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"}
|
|
@@ -20,6 +20,7 @@ export { registerContextCommands } from './builtins/context.js';
|
|
|
20
20
|
export { registerGoalCommand } from './builtins/goal.js';
|
|
21
21
|
export { registerSubgoalCommand } from './builtins/subgoal.js';
|
|
22
22
|
export { registerWorkflowCommands } from './builtins/workflow.js';
|
|
23
|
+
export { registerReviewCommand } from './builtins/review.js';
|
|
23
24
|
export { registerAgentEditCommand } from './agent-edit.js';
|
|
24
25
|
/**
|
|
25
26
|
* Initialize the command system with all built-in commands
|
|
@@ -11,6 +11,7 @@ import { registerContextCommands } from "./builtins/context.js";
|
|
|
11
11
|
import { registerGoalCommand } from "./builtins/goal.js";
|
|
12
12
|
import { registerSubgoalCommand } from "./builtins/subgoal.js";
|
|
13
13
|
import { registerWorkflowCommands } from "./builtins/workflow.js";
|
|
14
|
+
import { registerReviewCommand } from "./builtins/review.js";
|
|
14
15
|
import { registerAgentEditCommand } from "./agent-edit.js";
|
|
15
16
|
import { CommandContextImpl, createCommandContext } from "./context.js";
|
|
16
17
|
//#region src/chat-commands/index.ts
|
|
@@ -34,9 +35,10 @@ function initializeCommands() {
|
|
|
34
35
|
registerGoalCommand();
|
|
35
36
|
registerSubgoalCommand();
|
|
36
37
|
registerWorkflowCommands();
|
|
38
|
+
registerReviewCommand();
|
|
37
39
|
registerAgentEditCommand();
|
|
38
40
|
}
|
|
39
41
|
//#endregion
|
|
40
|
-
export { CommandContextImpl, CommandRegistry, commandRegistry, createCommandContext, generateSessionKey, getSessionDisplayName, initializeCommands, normalizeTelegramCommandName, parseSlashCommand, registerAgentEditCommand, registerConfigCommand, registerContextCommands, registerGoalCommand, registerModelCommands, registerSessionCommands, registerSubgoalCommand, registerSystemCommands, registerTTSCommands, registerThinkingCommands, registerWorkflowCommands };
|
|
42
|
+
export { CommandContextImpl, CommandRegistry, commandRegistry, createCommandContext, generateSessionKey, getSessionDisplayName, initializeCommands, normalizeTelegramCommandName, parseSlashCommand, registerAgentEditCommand, registerConfigCommand, registerContextCommands, registerGoalCommand, registerModelCommands, registerReviewCommand, registerSessionCommands, registerSubgoalCommand, registerSystemCommands, registerTTSCommands, registerThinkingCommands, registerWorkflowCommands };
|
|
41
43
|
|
|
42
44
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/chat-commands/index.ts"],"sourcesContent":["/**\n * Unified Command System\n *\n * Provides a platform-agnostic command system that works across\n * Telegram, Feishu, Web UI, CLI, and other channel surfaces.\n */\n\n// Built-in Commands (import first to avoid circular deps)\nimport { registerSessionCommands } from './builtins/session.js';\nimport { registerModelCommands } from './builtins/model.js';\nimport { registerSystemCommands } from './builtins/system.js';\nimport { registerTTSCommands } from './builtins/tts.js';\nimport { registerThinkingCommands } from './builtins/thinking.js';\nimport { registerConfigCommand } from './builtins/config.js';\nimport { registerContextCommands } from './builtins/context.js';\nimport { registerGoalCommand } from './builtins/goal.js';\nimport { registerSubgoalCommand } from './builtins/subgoal.js';\nimport { registerWorkflowCommands } from './builtins/workflow.js';\nimport { registerAgentEditCommand } from './agent-edit.js';\n\n// Types\nexport type {\n MessageSource,\n UnifiedMessage,\n PlatformMetadata,\n MessageAttachment,\n CommandDefinition,\n CommandCategory,\n CommandScope,\n CommandHandler,\n CommandResult,\n CommandContext,\n ReplyOptions,\n UIComponent,\n ButtonGroup,\n SelectMenu,\n ModelPicker,\n UsageDisplay,\n SessionList,\n TextInput,\n ProviderInfo,\n ModelInfo,\n UsageStats,\n SessionInfo,\n PlatformFeature,\n ChannelAdapter,\n ReplyPayload,\n} from './types.js';\n\n// Session display helpers\nexport { generateSessionKey, getSessionDisplayName, type SessionKeyContext } from './session-key.js';\n\n// Command parsing helpers\nexport { normalizeTelegramCommandName, parseSlashCommand } from './command-parse.js';\n\n// Registry\nexport { CommandRegistry, commandRegistry } from './registry.js';\nexport type { CommandRegistry as CommandRegistryType } from './types.js';\n\n// Context\nexport { CommandContextImpl, createCommandContext } from './context.js';\n\n// Built-in Commands\nexport { registerSessionCommands } from './builtins/session.js';\nexport { registerModelCommands } from './builtins/model.js';\nexport { registerSystemCommands } from './builtins/system.js';\nexport { registerTTSCommands } from './builtins/tts.js';\nexport { registerThinkingCommands } from './builtins/thinking.js';\nexport { registerConfigCommand } from './builtins/config.js';\nexport { registerContextCommands } from './builtins/context.js';\nexport { registerGoalCommand } from './builtins/goal.js';\nexport { registerSubgoalCommand } from './builtins/subgoal.js';\nexport { registerWorkflowCommands } from './builtins/workflow.js';\nexport { registerAgentEditCommand } from './agent-edit.js';\n\n/**\n * Initialize the command system with all built-in commands\n */\nexport function initializeCommands(): void {\n registerSessionCommands();\n registerModelCommands();\n registerSystemCommands();\n registerConfigCommand();\n registerContextCommands();\n registerTTSCommands();\n registerThinkingCommands();\n registerGoalCommand();\n registerSubgoalCommand();\n registerWorkflowCommands();\n registerAgentEditCommand();\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/chat-commands/index.ts"],"sourcesContent":["/**\n * Unified Command System\n *\n * Provides a platform-agnostic command system that works across\n * Telegram, Feishu, Web UI, CLI, and other channel surfaces.\n */\n\n// Built-in Commands (import first to avoid circular deps)\nimport { registerSessionCommands } from './builtins/session.js';\nimport { registerModelCommands } from './builtins/model.js';\nimport { registerSystemCommands } from './builtins/system.js';\nimport { registerTTSCommands } from './builtins/tts.js';\nimport { registerThinkingCommands } from './builtins/thinking.js';\nimport { registerConfigCommand } from './builtins/config.js';\nimport { registerContextCommands } from './builtins/context.js';\nimport { registerGoalCommand } from './builtins/goal.js';\nimport { registerSubgoalCommand } from './builtins/subgoal.js';\nimport { registerWorkflowCommands } from './builtins/workflow.js';\nimport { registerReviewCommand } from './builtins/review.js';\nimport { registerAgentEditCommand } from './agent-edit.js';\n\n// Types\nexport type {\n MessageSource,\n UnifiedMessage,\n PlatformMetadata,\n MessageAttachment,\n CommandDefinition,\n CommandCategory,\n CommandScope,\n CommandHandler,\n CommandResult,\n CommandContext,\n ReplyOptions,\n UIComponent,\n ButtonGroup,\n SelectMenu,\n ModelPicker,\n UsageDisplay,\n SessionList,\n TextInput,\n ProviderInfo,\n ModelInfo,\n UsageStats,\n SessionInfo,\n PlatformFeature,\n ChannelAdapter,\n ReplyPayload,\n} from './types.js';\n\n// Session display helpers\nexport { generateSessionKey, getSessionDisplayName, type SessionKeyContext } from './session-key.js';\n\n// Command parsing helpers\nexport { normalizeTelegramCommandName, parseSlashCommand } from './command-parse.js';\n\n// Registry\nexport { CommandRegistry, commandRegistry } from './registry.js';\nexport type { CommandRegistry as CommandRegistryType } from './types.js';\n\n// Context\nexport { CommandContextImpl, createCommandContext } from './context.js';\n\n// Built-in Commands\nexport { registerSessionCommands } from './builtins/session.js';\nexport { registerModelCommands } from './builtins/model.js';\nexport { registerSystemCommands } from './builtins/system.js';\nexport { registerTTSCommands } from './builtins/tts.js';\nexport { registerThinkingCommands } from './builtins/thinking.js';\nexport { registerConfigCommand } from './builtins/config.js';\nexport { registerContextCommands } from './builtins/context.js';\nexport { registerGoalCommand } from './builtins/goal.js';\nexport { registerSubgoalCommand } from './builtins/subgoal.js';\nexport { registerWorkflowCommands } from './builtins/workflow.js';\nexport { registerReviewCommand } from './builtins/review.js';\nexport { registerAgentEditCommand } from './agent-edit.js';\n\n/**\n * Initialize the command system with all built-in commands\n */\nexport function initializeCommands(): void {\n registerSessionCommands();\n registerModelCommands();\n registerSystemCommands();\n registerConfigCommand();\n registerContextCommands();\n registerTTSCommands();\n registerThinkingCommands();\n registerGoalCommand();\n registerSubgoalCommand();\n registerWorkflowCommands();\n registerReviewCommand();\n registerAgentEditCommand();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,SAAgB,qBAA2B;AACzC,0BAAyB;AACzB,wBAAuB;AACvB,yBAAwB;AACxB,wBAAuB;AACvB,0BAAyB;AACzB,sBAAqB;AACrB,2BAA0B;AAC1B,sBAAqB;AACrB,yBAAwB;AACxB,2BAA0B;AAC1B,wBAAuB;AACvB,2BAA0B"}
|
|
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
|
|
|
52
52
|
id: "database-schema",
|
|
53
53
|
label: "Database schema",
|
|
54
54
|
status: "pass",
|
|
55
|
-
message: `SQLite schema v${status.dbVersion} (current release
|
|
55
|
+
message: `SQLite schema v${status.dbVersion} (current release v21).`,
|
|
56
56
|
hints: []
|
|
57
57
|
};
|
|
58
58
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { init_paths, resolveConfigPath } from "../../../config/paths.js";
|
|
2
2
|
import { loadConfig } from "../../../config/loader.js";
|
|
3
3
|
import "../../../config/index.js";
|
|
4
|
-
import { isRestartEnabled } from "../../../config/commands.flags.js";
|
|
5
4
|
import { resolveGatewayService } from "../../../daemon/service.js";
|
|
5
|
+
import { isRestartEnabled } from "../../../config/commands.flags.js";
|
|
6
6
|
import { authorizeGatewaySigusr1Restart, writeGatewayRestartIntentSync } from "../../../infra/restart.js";
|
|
7
7
|
import { findVerifiedGatewayListenerPidsOnPortSync, formatGatewayPidList, signalVerifiedGatewayPidSync } from "../../../infra/gateway-processes.js";
|
|
8
8
|
import { runServiceRestart, runServiceStop } from "./lifecycle-core.js";
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Built-in agent tool `name` values for gateway admin UI (disable toggles).
|
|
3
3
|
* Extension tools are not listed; users can still add arbitrary strings in config.
|
|
4
4
|
*/
|
|
5
|
-
export declare const GATEWAY_BUILTIN_TOOL_IDS: readonly ["read_file", "write_file", "
|
|
5
|
+
export declare const GATEWAY_BUILTIN_TOOL_IDS: readonly ["read_file", "write_file", "apply_patch", "list_dir", "grep", "find", "exec_command", "update_plan", "session_status", "dreaming", "tool_manual", "clarify", "todo", "skills_list", "skill_view", "skill_manage", "web_search", "web_fetch", "web_extract", "send_message", "send_media", "read_media", "create_share", "text_to_speech", "memory_search", "memory_get", "curated_memory", "session_search", "automation", "workflow", "delegate_task", "execute_code", "image", "image_generate", "browser_use", "extensions", "bundle-mcp"];
|
|
6
6
|
export type GatewayBuiltinToolId = (typeof GATEWAY_BUILTIN_TOOL_IDS)[number];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-builtin-tools.js","names":[],"sources":["../../../src/gateway/agent-builtin-tools.ts"],"sourcesContent":["/**\n * Built-in agent tool `name` values for gateway admin UI (disable toggles).\n * Extension tools are not listed; users can still add arbitrary strings in config.\n */\nexport const GATEWAY_BUILTIN_TOOL_IDS = [\n 'read_file',\n 'write_file',\n '
|
|
1
|
+
{"version":3,"file":"agent-builtin-tools.js","names":[],"sources":["../../../src/gateway/agent-builtin-tools.ts"],"sourcesContent":["/**\n * Built-in agent tool `name` values for gateway admin UI (disable toggles).\n * Extension tools are not listed; users can still add arbitrary strings in config.\n */\nexport const GATEWAY_BUILTIN_TOOL_IDS = [\n 'read_file',\n 'write_file',\n 'apply_patch',\n 'list_dir',\n 'grep',\n 'find',\n 'exec_command',\n 'update_plan',\n 'session_status',\n 'dreaming',\n 'tool_manual',\n 'clarify',\n 'todo',\n 'skills_list',\n 'skill_view',\n 'skill_manage',\n 'web_search',\n 'web_fetch',\n 'web_extract',\n 'send_message',\n 'send_media',\n 'read_media',\n 'create_share',\n 'text_to_speech',\n 'memory_search',\n 'memory_get',\n 'curated_memory',\n 'session_search',\n 'automation',\n 'workflow',\n 'delegate_task',\n 'execute_code',\n 'image',\n 'image_generate',\n 'browser_use',\n 'extensions',\n 'bundle-mcp',\n] as const;\n\nexport type GatewayBuiltinToolId = (typeof GATEWAY_BUILTIN_TOOL_IDS)[number];\n"],"mappings":";;;;;AAIA,MAAa,2BAA2B;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}
|
|
@@ -15,7 +15,12 @@ export declare class ChatStreamMapper {
|
|
|
15
15
|
private currentAssistantMessageId;
|
|
16
16
|
private lastAssistantMessageId;
|
|
17
17
|
private currentAssistantText;
|
|
18
|
+
private currentAssistantReviewEmitted;
|
|
18
19
|
private toolCallToMessageId;
|
|
20
|
+
private turnDiffs;
|
|
21
|
+
private turnDiffFiles;
|
|
22
|
+
private turnDiffAdded;
|
|
23
|
+
private turnDiffRemoved;
|
|
19
24
|
private started;
|
|
20
25
|
private ended;
|
|
21
26
|
constructor(opts: ChatStreamMapperOptions);
|
|
@@ -32,4 +37,5 @@ export declare class ChatStreamMapper {
|
|
|
32
37
|
private ensureAssistantMessageId;
|
|
33
38
|
private nextAssistantMessageId;
|
|
34
39
|
private make;
|
|
40
|
+
private recordPatchDiff;
|
|
35
41
|
}
|
|
@@ -4,7 +4,12 @@ var ChatStreamMapper = class {
|
|
|
4
4
|
currentAssistantMessageId;
|
|
5
5
|
lastAssistantMessageId;
|
|
6
6
|
currentAssistantText = "";
|
|
7
|
+
currentAssistantReviewEmitted = false;
|
|
7
8
|
toolCallToMessageId = /* @__PURE__ */ new Map();
|
|
9
|
+
turnDiffs = [];
|
|
10
|
+
turnDiffFiles = /* @__PURE__ */ new Set();
|
|
11
|
+
turnDiffAdded = 0;
|
|
12
|
+
turnDiffRemoved = 0;
|
|
8
13
|
started = false;
|
|
9
14
|
ended = false;
|
|
10
15
|
constructor(opts) {
|
|
@@ -80,12 +85,21 @@ var ChatStreamMapper = class {
|
|
|
80
85
|
const messageId = this.nextAssistantMessageId();
|
|
81
86
|
this.currentAssistantMessageId = messageId;
|
|
82
87
|
this.currentAssistantText = "";
|
|
88
|
+
this.currentAssistantReviewEmitted = false;
|
|
83
89
|
return [this.make("assistant_message_start", { messageId })];
|
|
84
90
|
}
|
|
85
91
|
mapMessageUpdate(event) {
|
|
86
92
|
const message = event.message;
|
|
87
93
|
if (message?.role !== "assistant") return [];
|
|
88
94
|
const messageId = this.ensureAssistantMessageId();
|
|
95
|
+
const review = extractReview(message);
|
|
96
|
+
if (review && !this.currentAssistantReviewEmitted) {
|
|
97
|
+
this.currentAssistantReviewEmitted = true;
|
|
98
|
+
return [this.make("review", {
|
|
99
|
+
messageId,
|
|
100
|
+
review
|
|
101
|
+
})];
|
|
102
|
+
}
|
|
89
103
|
const delta = event.assistantMessageEvent;
|
|
90
104
|
if (delta?.type === "text_delta" && typeof delta.delta === "string" && delta.delta) {
|
|
91
105
|
const text = extractTextFromMessage(message);
|
|
@@ -118,6 +132,14 @@ var ChatStreamMapper = class {
|
|
|
118
132
|
if (message?.role !== "assistant") return [];
|
|
119
133
|
const messageId = this.ensureAssistantMessageId();
|
|
120
134
|
const events = [];
|
|
135
|
+
const review = extractReview(message);
|
|
136
|
+
if (review && !this.currentAssistantReviewEmitted) {
|
|
137
|
+
this.currentAssistantReviewEmitted = true;
|
|
138
|
+
events.push(this.make("review", {
|
|
139
|
+
messageId,
|
|
140
|
+
review
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
121
143
|
const text = extractTextFromMessage(message);
|
|
122
144
|
const suffix = appendSuffix(this.currentAssistantText, text);
|
|
123
145
|
if (suffix) events.push(this.make("assistant_delta", {
|
|
@@ -126,6 +148,19 @@ var ChatStreamMapper = class {
|
|
|
126
148
|
}));
|
|
127
149
|
this.currentAssistantText = text || this.currentAssistantText;
|
|
128
150
|
events.push(this.make("thinking_end", { messageId }));
|
|
151
|
+
if (this.turnDiffs.length > 0) {
|
|
152
|
+
events.push(this.make("turn_diff", {
|
|
153
|
+
messageId,
|
|
154
|
+
files: [...this.turnDiffFiles],
|
|
155
|
+
diff: this.turnDiffs.join("\n"),
|
|
156
|
+
added: this.turnDiffAdded,
|
|
157
|
+
removed: this.turnDiffRemoved
|
|
158
|
+
}));
|
|
159
|
+
this.turnDiffs = [];
|
|
160
|
+
this.turnDiffFiles.clear();
|
|
161
|
+
this.turnDiffAdded = 0;
|
|
162
|
+
this.turnDiffRemoved = 0;
|
|
163
|
+
}
|
|
129
164
|
events.push(this.make("assistant_message_end", {
|
|
130
165
|
messageId,
|
|
131
166
|
usage: extractUsage(message)
|
|
@@ -133,19 +168,31 @@ var ChatStreamMapper = class {
|
|
|
133
168
|
this.lastAssistantMessageId = messageId;
|
|
134
169
|
this.currentAssistantMessageId = void 0;
|
|
135
170
|
this.currentAssistantText = "";
|
|
171
|
+
this.currentAssistantReviewEmitted = false;
|
|
136
172
|
return events;
|
|
137
173
|
}
|
|
138
174
|
mapToolStart(event) {
|
|
139
175
|
const toolCallId = String(event.toolCallId ?? "");
|
|
140
176
|
if (!toolCallId) return [];
|
|
141
177
|
const messageId = this.ensureAssistantMessageId();
|
|
178
|
+
const toolName = String(event.toolName ?? "unknown");
|
|
142
179
|
this.toolCallToMessageId.set(toolCallId, messageId);
|
|
143
|
-
|
|
180
|
+
const events = [this.make("tool_start", {
|
|
144
181
|
messageId,
|
|
145
182
|
toolCallId,
|
|
146
|
-
toolName
|
|
183
|
+
toolName,
|
|
147
184
|
args: event.args
|
|
148
185
|
})];
|
|
186
|
+
if (toolName === "exec_command") {
|
|
187
|
+
const args = asRecord(event.args);
|
|
188
|
+
events.push(this.make("command_started", {
|
|
189
|
+
messageId,
|
|
190
|
+
toolCallId,
|
|
191
|
+
command: String(args?.cmd ?? args?.command ?? ""),
|
|
192
|
+
cwd: typeof args?.cwd === "string" ? args.cwd : void 0
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
return events;
|
|
149
196
|
}
|
|
150
197
|
mapToolUpdate(event) {
|
|
151
198
|
const toolCallId = String(event.toolCallId ?? "");
|
|
@@ -154,27 +201,79 @@ var ChatStreamMapper = class {
|
|
|
154
201
|
const partial = event.partialResult;
|
|
155
202
|
const details = extractDetails(partial);
|
|
156
203
|
const textDelta = extractText(partial);
|
|
157
|
-
|
|
204
|
+
const toolName = String(event.toolName ?? "unknown");
|
|
205
|
+
const events = [this.make("tool_update", {
|
|
158
206
|
messageId,
|
|
159
207
|
toolCallId,
|
|
160
|
-
toolName
|
|
208
|
+
toolName,
|
|
161
209
|
details,
|
|
162
210
|
textDelta
|
|
163
211
|
})];
|
|
212
|
+
if (toolName === "exec_command") {
|
|
213
|
+
const rec = asRecord(details);
|
|
214
|
+
if (rec?.kind === "command_output_delta") {
|
|
215
|
+
const stream = rec.stream === "stderr" ? "stderr" : "stdout";
|
|
216
|
+
const delta = typeof rec.delta === "string" ? rec.delta : "";
|
|
217
|
+
if (delta) events.push(this.make("command_output_delta", {
|
|
218
|
+
messageId,
|
|
219
|
+
toolCallId,
|
|
220
|
+
stream,
|
|
221
|
+
delta
|
|
222
|
+
}));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return events;
|
|
164
226
|
}
|
|
165
227
|
mapToolEnd(event) {
|
|
166
228
|
const toolCallId = String(event.toolCallId ?? "");
|
|
167
229
|
if (!toolCallId) return [];
|
|
168
230
|
const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();
|
|
169
231
|
const result = normalizeToolResult(event.result);
|
|
170
|
-
|
|
232
|
+
const toolName = String(event.toolName ?? "unknown");
|
|
233
|
+
const events = [this.make("tool_end", {
|
|
171
234
|
messageId,
|
|
172
235
|
toolCallId,
|
|
173
|
-
toolName
|
|
236
|
+
toolName,
|
|
174
237
|
status: event.isError ? "error" : "success",
|
|
175
238
|
result,
|
|
176
239
|
errorMessage: event.isError ? result?.text : void 0
|
|
177
240
|
})];
|
|
241
|
+
const details = asRecord(result?.details);
|
|
242
|
+
if (toolName === "exec_command" && details) events.push(this.make("command_completed", {
|
|
243
|
+
messageId,
|
|
244
|
+
toolCallId,
|
|
245
|
+
command: typeof details.command === "string" ? details.command : "",
|
|
246
|
+
cwd: typeof details.cwd === "string" ? details.cwd : void 0,
|
|
247
|
+
exitCode: typeof details.exitCode === "number" ? details.exitCode : null,
|
|
248
|
+
durationMs: typeof details.durationMs === "number" ? details.durationMs : void 0,
|
|
249
|
+
timedOut: details.timedOut === true,
|
|
250
|
+
truncated: details.truncated === true
|
|
251
|
+
}));
|
|
252
|
+
if (toolName === "apply_patch" && details) {
|
|
253
|
+
const changes = Array.isArray(details.changes) ? details.changes : [];
|
|
254
|
+
const diff = typeof details.diff === "string" ? details.diff : "";
|
|
255
|
+
const added = typeof details.added === "number" ? details.added : 0;
|
|
256
|
+
const removed = typeof details.removed === "number" ? details.removed : 0;
|
|
257
|
+
if (diff || changes.length > 0) {
|
|
258
|
+
this.recordPatchDiff(details);
|
|
259
|
+
events.push(this.make("patch_applied", {
|
|
260
|
+
messageId,
|
|
261
|
+
toolCallId,
|
|
262
|
+
changes,
|
|
263
|
+
diff,
|
|
264
|
+
added,
|
|
265
|
+
removed
|
|
266
|
+
}));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (toolName === "update_plan" && details) {
|
|
270
|
+
const plan = extractTurnPlan(details);
|
|
271
|
+
if (plan) events.push(this.make("turn_plan", {
|
|
272
|
+
messageId,
|
|
273
|
+
...plan
|
|
274
|
+
}));
|
|
275
|
+
}
|
|
276
|
+
return events;
|
|
178
277
|
}
|
|
179
278
|
ensureAssistantMessageId() {
|
|
180
279
|
if (!this.currentAssistantMessageId) this.currentAssistantMessageId = this.nextAssistantMessageId();
|
|
@@ -193,6 +292,18 @@ var ChatStreamMapper = class {
|
|
|
193
292
|
payload
|
|
194
293
|
};
|
|
195
294
|
}
|
|
295
|
+
recordPatchDiff(details) {
|
|
296
|
+
const diff = typeof details.diff === "string" ? details.diff : "";
|
|
297
|
+
if (diff) this.turnDiffs.push(diff);
|
|
298
|
+
if (typeof details.added === "number") this.turnDiffAdded += details.added;
|
|
299
|
+
if (typeof details.removed === "number") this.turnDiffRemoved += details.removed;
|
|
300
|
+
const changes = Array.isArray(details.changes) ? details.changes : [];
|
|
301
|
+
for (const change of changes) {
|
|
302
|
+
const rec = asRecord(change);
|
|
303
|
+
const path = typeof rec?.moveTo === "string" ? rec.moveTo : typeof rec?.path === "string" ? rec.path : void 0;
|
|
304
|
+
if (path) this.turnDiffFiles.add(path);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
196
307
|
};
|
|
197
308
|
function userMessageFromLegacyEvent(event) {
|
|
198
309
|
return {
|
|
@@ -205,6 +316,18 @@ function userMessageFromLegacyEvent(event) {
|
|
|
205
316
|
function extractTextFromMessage(message) {
|
|
206
317
|
return extractText(message.content);
|
|
207
318
|
}
|
|
319
|
+
function extractReview(message) {
|
|
320
|
+
const metadata = message.metadata;
|
|
321
|
+
const metadataReview = asRecord(metadata)?.review;
|
|
322
|
+
if (isReviewBlock(metadataReview)) return metadataReview;
|
|
323
|
+
const content = message.content;
|
|
324
|
+
if (Array.isArray(content)) {
|
|
325
|
+
for (const block of content) if (isReviewBlock(block)) return block;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
function isReviewBlock(value) {
|
|
329
|
+
return !!value && typeof value === "object" && !Array.isArray(value) && value.type === "review";
|
|
330
|
+
}
|
|
208
331
|
function extractText(value) {
|
|
209
332
|
if (typeof value === "string") return value;
|
|
210
333
|
if (!Array.isArray(value)) return void 0;
|
|
@@ -238,6 +361,9 @@ function extractDetails(value) {
|
|
|
238
361
|
if (!value || typeof value !== "object") return void 0;
|
|
239
362
|
return value.details;
|
|
240
363
|
}
|
|
364
|
+
function asRecord(value) {
|
|
365
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
366
|
+
}
|
|
241
367
|
function normalizeToolResult(value) {
|
|
242
368
|
if (value == null) return void 0;
|
|
243
369
|
if (typeof value === "string") return { text: value };
|
|
@@ -249,6 +375,23 @@ function normalizeToolResult(value) {
|
|
|
249
375
|
text: extractText(rec.content) ?? (typeof rec.text === "string" ? rec.text : void 0)
|
|
250
376
|
};
|
|
251
377
|
}
|
|
378
|
+
function extractTurnPlan(details) {
|
|
379
|
+
const plan = (Array.isArray(details.plan) ? details.plan : []).map((item) => {
|
|
380
|
+
const rec = asRecord(item);
|
|
381
|
+
const step = typeof rec?.step === "string" ? rec.step.trim() : "";
|
|
382
|
+
const status = rec?.status;
|
|
383
|
+
if (!step || status !== "pending" && status !== "in_progress" && status !== "completed") return;
|
|
384
|
+
return {
|
|
385
|
+
step,
|
|
386
|
+
status
|
|
387
|
+
};
|
|
388
|
+
}).filter((item) => Boolean(item));
|
|
389
|
+
if (plan.length === 0) return void 0;
|
|
390
|
+
return {
|
|
391
|
+
explanation: typeof details.explanation === "string" && details.explanation.trim() ? details.explanation.trim() : void 0,
|
|
392
|
+
plan
|
|
393
|
+
};
|
|
394
|
+
}
|
|
252
395
|
//#endregion
|
|
253
396
|
export { ChatStreamMapper };
|
|
254
397
|
|