@orion-agents/orion-code 0.1.1 → 0.1.3
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 +165 -68
- package/README.zh-CN.md +252 -212
- package/dist/cli.js +13 -17
- package/dist/cli.js.map +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +381 -168
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/target-command.d.ts.map +1 -1
- package/dist/commands/target-command.js +42 -8
- package/dist/commands/target-command.js.map +1 -1
- package/dist/commands/types.d.ts +3 -1
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +2 -2
- package/dist/core/agent.js.map +1 -1
- package/dist/framework/external-assertion.d.ts +65 -0
- package/dist/framework/external-assertion.d.ts.map +1 -0
- package/dist/framework/external-assertion.js +571 -0
- package/dist/framework/external-assertion.js.map +1 -0
- package/dist/framework/index.d.ts +6 -4
- package/dist/framework/index.d.ts.map +1 -1
- package/dist/framework/index.js +4 -1
- package/dist/framework/index.js.map +1 -1
- package/dist/framework/query.d.ts +18 -1
- package/dist/framework/query.d.ts.map +1 -1
- package/dist/framework/query.js +43 -23
- package/dist/framework/query.js.map +1 -1
- package/dist/framework/tool-scheduler.d.ts +63 -1
- package/dist/framework/tool-scheduler.d.ts.map +1 -1
- package/dist/framework/tool-scheduler.js +183 -51
- package/dist/framework/tool-scheduler.js.map +1 -1
- package/dist/framework/tool-serializer.d.ts.map +1 -1
- package/dist/framework/tool-serializer.js +20 -4
- package/dist/framework/tool-serializer.js.map +1 -1
- package/dist/framework/tool.d.ts +17 -5
- package/dist/framework/tool.d.ts.map +1 -1
- package/dist/framework/tool.js +2 -0
- package/dist/framework/tool.js.map +1 -1
- package/dist/harness/safety.d.ts.map +1 -1
- package/dist/harness/safety.js +19 -3
- package/dist/harness/safety.js.map +1 -1
- package/dist/init.d.ts +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +115 -34
- package/dist/init.js.map +1 -1
- package/dist/ink-ui/screens/ReplScreen.d.ts +2 -1
- package/dist/ink-ui/screens/ReplScreen.d.ts.map +1 -1
- package/dist/ink-ui/screens/ReplScreen.js +65 -0
- package/dist/ink-ui/screens/ReplScreen.js.map +1 -1
- package/dist/memory/storage.d.ts.map +1 -1
- package/dist/memory/storage.js +1 -0
- package/dist/memory/storage.js.map +1 -1
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/memory/store.js +11 -5
- package/dist/memory/store.js.map +1 -1
- package/dist/print-ui/launch.d.ts +6 -1
- package/dist/print-ui/launch.d.ts.map +1 -1
- package/dist/print-ui/launch.js +109 -9
- package/dist/print-ui/launch.js.map +1 -1
- package/dist/product/identity.d.ts +2 -2
- package/dist/product/identity.d.ts.map +1 -1
- package/dist/product/identity.js +2 -2
- package/dist/product/identity.js.map +1 -1
- package/dist/product/index.d.ts +2 -1
- package/dist/product/index.d.ts.map +1 -1
- package/dist/product/index.js +5 -1
- package/dist/product/index.js.map +1 -1
- package/dist/product/version.d.ts +12 -0
- package/dist/product/version.d.ts.map +1 -0
- package/dist/product/version.js +31 -0
- package/dist/product/version.js.map +1 -0
- package/dist/runtime/agent-runtime-controller.d.ts +35 -0
- package/dist/runtime/agent-runtime-controller.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-controller.js +975 -149
- package/dist/runtime/agent-runtime-controller.js.map +1 -1
- package/dist/runtime/agent-runtime-protocol.d.ts +20 -3
- package/dist/runtime/agent-runtime-protocol.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-protocol.js +12 -0
- package/dist/runtime/agent-runtime-protocol.js.map +1 -1
- package/dist/runtime/chat-controller.d.ts +12 -0
- package/dist/runtime/chat-controller.d.ts.map +1 -1
- package/dist/runtime/chat-controller.js +213 -19
- package/dist/runtime/chat-controller.js.map +1 -1
- package/dist/runtime/goals/accounting.d.ts +28 -0
- package/dist/runtime/goals/accounting.d.ts.map +1 -1
- package/dist/runtime/goals/accounting.js +69 -0
- package/dist/runtime/goals/accounting.js.map +1 -1
- package/dist/runtime/goals/completion-audit.d.ts +13 -8
- package/dist/runtime/goals/completion-audit.d.ts.map +1 -1
- package/dist/runtime/goals/completion-audit.js +598 -16
- package/dist/runtime/goals/completion-audit.js.map +1 -1
- package/dist/runtime/goals/coordinator.d.ts +44 -5
- package/dist/runtime/goals/coordinator.d.ts.map +1 -1
- package/dist/runtime/goals/coordinator.js +1124 -58
- package/dist/runtime/goals/coordinator.js.map +1 -1
- package/dist/runtime/goals/evidence.d.ts +37 -0
- package/dist/runtime/goals/evidence.d.ts.map +1 -0
- package/dist/runtime/goals/evidence.js +300 -0
- package/dist/runtime/goals/evidence.js.map +1 -0
- package/dist/runtime/goals/presentation.d.ts +4 -0
- package/dist/runtime/goals/presentation.d.ts.map +1 -0
- package/dist/runtime/goals/presentation.js +50 -0
- package/dist/runtime/goals/presentation.js.map +1 -0
- package/dist/runtime/goals/prompt.d.ts.map +1 -1
- package/dist/runtime/goals/prompt.js +38 -8
- package/dist/runtime/goals/prompt.js.map +1 -1
- package/dist/runtime/goals/tools.d.ts +18 -1
- package/dist/runtime/goals/tools.d.ts.map +1 -1
- package/dist/runtime/goals/tools.js +310 -30
- package/dist/runtime/goals/tools.js.map +1 -1
- package/dist/runtime/goals/types.d.ts +247 -7
- package/dist/runtime/goals/types.d.ts.map +1 -1
- package/dist/runtime/goals/types.js +8 -2
- package/dist/runtime/goals/types.js.map +1 -1
- package/dist/runtime/subagents/child-executor-guard.d.ts +12 -4
- package/dist/runtime/subagents/child-executor-guard.d.ts.map +1 -1
- package/dist/runtime/subagents/child-executor-guard.js +397 -61
- package/dist/runtime/subagents/child-executor-guard.js.map +1 -1
- package/dist/runtime/subagents/presets.d.ts +4 -5
- package/dist/runtime/subagents/presets.d.ts.map +1 -1
- package/dist/runtime/subagents/presets.js +18 -33
- package/dist/runtime/subagents/presets.js.map +1 -1
- package/dist/runtime/subagents/production.d.ts +3 -1
- package/dist/runtime/subagents/production.d.ts.map +1 -1
- package/dist/runtime/subagents/production.js +37 -7
- package/dist/runtime/subagents/production.js.map +1 -1
- package/dist/runtime/subagents/runner.d.ts.map +1 -1
- package/dist/runtime/subagents/runner.js +24 -3
- package/dist/runtime/subagents/runner.js.map +1 -1
- package/dist/runtime/subagents/runtime-integration.d.ts +3 -0
- package/dist/runtime/subagents/runtime-integration.d.ts.map +1 -1
- package/dist/runtime/subagents/runtime-integration.js +18 -7
- package/dist/runtime/subagents/runtime-integration.js.map +1 -1
- package/dist/runtime/subagents/supervisor.d.ts +4 -4
- package/dist/runtime/subagents/supervisor.d.ts.map +1 -1
- package/dist/runtime/subagents/supervisor.js +39 -19
- package/dist/runtime/subagents/supervisor.js.map +1 -1
- package/dist/runtime/subagents/types.d.ts +7 -0
- package/dist/runtime/subagents/types.d.ts.map +1 -1
- package/dist/runtime/subagents/types.js +12 -1
- package/dist/runtime/subagents/types.js.map +1 -1
- package/dist/runtime/turn-controller.d.ts.map +1 -1
- package/dist/runtime/turn-controller.js +3 -1
- package/dist/runtime/turn-controller.js.map +1 -1
- package/dist/runtime/ui-events.d.ts +23 -0
- package/dist/runtime/ui-events.d.ts.map +1 -1
- package/dist/runtime/ui-events.js +5 -5
- package/dist/runtime/ui-events.js.map +1 -1
- package/dist/services/config.d.ts +1 -1
- package/dist/services/config.d.ts.map +1 -1
- package/dist/services/config.js +55 -49
- package/dist/services/config.js.map +1 -1
- package/dist/services/doctor.d.ts.map +1 -1
- package/dist/services/doctor.js +163 -17
- package/dist/services/doctor.js.map +1 -1
- package/dist/services/global-config.d.ts +31 -0
- package/dist/services/global-config.d.ts.map +1 -1
- package/dist/services/global-config.js.map +1 -1
- package/dist/services/goal-storage.d.ts +9 -4
- package/dist/services/goal-storage.d.ts.map +1 -1
- package/dist/services/goal-storage.js +1113 -75
- package/dist/services/goal-storage.js.map +1 -1
- package/dist/services/llm.d.ts +19 -0
- package/dist/services/llm.d.ts.map +1 -1
- package/dist/services/llm.js +153 -20
- package/dist/services/llm.js.map +1 -1
- package/dist/services/model-catalog.d.ts +2 -0
- package/dist/services/model-catalog.d.ts.map +1 -1
- package/dist/services/model-catalog.js +25 -15
- package/dist/services/model-catalog.js.map +1 -1
- package/dist/services/model-context.d.ts.map +1 -1
- package/dist/services/model-context.js +36 -0
- package/dist/services/model-context.js.map +1 -1
- package/dist/services/model-registry.d.ts +1 -1
- package/dist/services/model-registry.d.ts.map +1 -1
- package/dist/services/model-registry.js +101 -19
- package/dist/services/model-registry.js.map +1 -1
- package/dist/services/provider-resilience/coordinator.d.ts +2 -1
- package/dist/services/provider-resilience/coordinator.d.ts.map +1 -1
- package/dist/services/provider-resilience/coordinator.js +7 -6
- package/dist/services/provider-resilience/coordinator.js.map +1 -1
- package/dist/services/provider-resilience/error-classifier.d.ts.map +1 -1
- package/dist/services/provider-resilience/error-classifier.js +67 -17
- package/dist/services/provider-resilience/error-classifier.js.map +1 -1
- package/dist/services/provider-resilience/types.d.ts +1 -1
- package/dist/services/provider-resilience/types.d.ts.map +1 -1
- package/dist/services/provider-resilience/types.js.map +1 -1
- package/dist/services/redaction.d.ts.map +1 -1
- package/dist/services/redaction.js +9 -1
- package/dist/services/redaction.js.map +1 -1
- package/dist/services/session-storage.d.ts +12 -1
- package/dist/services/session-storage.d.ts.map +1 -1
- package/dist/services/session-storage.js +23 -7
- package/dist/services/session-storage.js.map +1 -1
- package/dist/services/storage-maintenance.d.ts +73 -3
- package/dist/services/storage-maintenance.d.ts.map +1 -1
- package/dist/services/storage-maintenance.js +771 -104
- package/dist/services/storage-maintenance.js.map +1 -1
- package/dist/services/task-manager.d.ts.map +1 -1
- package/dist/services/task-manager.js +2 -2
- package/dist/services/task-manager.js.map +1 -1
- package/dist/services/tool-allowlist.d.ts +100 -0
- package/dist/services/tool-allowlist.d.ts.map +1 -0
- package/dist/services/tool-allowlist.js +250 -0
- package/dist/services/tool-allowlist.js.map +1 -0
- package/dist/services/web-search-adapters.d.ts.map +1 -1
- package/dist/services/web-search-adapters.js +89 -49
- package/dist/services/web-search-adapters.js.map +1 -1
- package/dist/services/web-search-mcp.d.ts.map +1 -1
- package/dist/services/web-search-mcp.js +34 -37
- package/dist/services/web-search-mcp.js.map +1 -1
- package/dist/services/workspace-state.d.ts +4 -0
- package/dist/services/workspace-state.d.ts.map +1 -1
- package/dist/services/workspace-state.js +30 -9
- package/dist/services/workspace-state.js.map +1 -1
- package/dist/terminal-ui/launch.d.ts +24 -2
- package/dist/terminal-ui/launch.d.ts.map +1 -1
- package/dist/terminal-ui/launch.js +166 -8
- package/dist/terminal-ui/launch.js.map +1 -1
- package/dist/tools/git.d.ts +4 -0
- package/dist/tools/git.d.ts.map +1 -1
- package/dist/tools/git.js +585 -30
- package/dist/tools/git.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +79 -11
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/mcp.d.ts.map +1 -1
- package/dist/tools/mcp.js +20 -12
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/sandbox.d.ts +139 -0
- package/dist/tools/sandbox.d.ts.map +1 -0
- package/dist/tools/sandbox.js +485 -0
- package/dist/tools/sandbox.js.map +1 -0
- package/dist/tools/web.d.ts.map +1 -1
- package/dist/tools/web.js +149 -54
- package/dist/tools/web.js.map +1 -1
- package/dist/tui-ui/launch.d.ts.map +1 -1
- package/dist/tui-ui/launch.js +46 -8
- package/dist/tui-ui/launch.js.map +1 -1
- package/dist/tui-ui/layout.d.ts.map +1 -1
- package/dist/tui-ui/layout.js +98 -23
- package/dist/tui-ui/layout.js.map +1 -1
- package/dist/tui-ui/pickers.d.ts.map +1 -1
- package/dist/tui-ui/pickers.js +4 -3
- package/dist/tui-ui/pickers.js.map +1 -1
- package/dist/tui-ui/runner.d.ts +7 -0
- package/dist/tui-ui/runner.d.ts.map +1 -1
- package/dist/tui-ui/runner.js +95 -1
- package/dist/tui-ui/runner.js.map +1 -1
- package/dist/tui-ui/state.d.ts +25 -1
- package/dist/tui-ui/state.d.ts.map +1 -1
- package/dist/tui-ui/state.js +95 -37
- package/dist/tui-ui/state.js.map +1 -1
- package/dist/tui-ui/terminal-image.d.ts +3 -13
- package/dist/tui-ui/terminal-image.d.ts.map +1 -1
- package/dist/tui-ui/terminal-image.js +5 -160
- package/dist/tui-ui/terminal-image.js.map +1 -1
- package/dist/utils/mask.d.ts +28 -0
- package/dist/utils/mask.d.ts.map +1 -0
- package/dist/utils/mask.js +54 -0
- package/dist/utils/mask.js.map +1 -0
- package/package.json +14 -9
- package/dist/core/state.d.ts +0 -94
- package/dist/core/state.d.ts.map +0 -1
- package/dist/core/state.js +0 -178
- package/dist/core/state.js.map +0 -1
- package/dist/ink/bidi.d.ts +0 -16
- package/dist/ink/bidi.d.ts.map +0 -1
- package/dist/ink/bidi.js +0 -124
- package/dist/ink/bidi.js.map +0 -1
- package/dist/ink/clearTerminal.d.ts +0 -14
- package/dist/ink/clearTerminal.d.ts.map +0 -1
- package/dist/ink/clearTerminal.js +0 -63
- package/dist/ink/clearTerminal.js.map +0 -1
- package/dist/ink/colorize.d.ts +0 -17
- package/dist/ink/colorize.d.ts.map +0 -1
- package/dist/ink/colorize.js +0 -208
- package/dist/ink/colorize.js.map +0 -1
- package/dist/ink/components/App.d.ts +0 -73
- package/dist/ink/components/App.d.ts.map +0 -1
- package/dist/ink/components/App.js +0 -646
- package/dist/ink/components/App.js.map +0 -1
- package/dist/ink/components/AppContext.d.ts +0 -12
- package/dist/ink/components/AppContext.d.ts.map +0 -1
- package/dist/ink/components/AppContext.js +0 -14
- package/dist/ink/components/AppContext.js.map +0 -1
- package/dist/ink/components/Box.d.ts +0 -44
- package/dist/ink/components/Box.d.ts.map +0 -1
- package/dist/ink/components/Box.js +0 -191
- package/dist/ink/components/Box.js.map +0 -1
- package/dist/ink/components/ClockContext.d.ts +0 -9
- package/dist/ink/components/ClockContext.d.ts.map +0 -1
- package/dist/ink/components/ClockContext.js +0 -146
- package/dist/ink/components/ClockContext.js.map +0 -1
- package/dist/ink/components/CursorDeclarationContext.d.ts +0 -23
- package/dist/ink/components/CursorDeclarationContext.d.ts.map +0 -1
- package/dist/ink/components/CursorDeclarationContext.js +0 -6
- package/dist/ink/components/CursorDeclarationContext.js.map +0 -1
- package/dist/ink/components/ErrorOverview.d.ts +0 -6
- package/dist/ink/components/ErrorOverview.d.ts.map +0 -1
- package/dist/ink/components/ErrorOverview.js +0 -27
- package/dist/ink/components/ErrorOverview.js.map +0 -1
- package/dist/ink/components/Newline.d.ts +0 -13
- package/dist/ink/components/Newline.d.ts.map +0 -1
- package/dist/ink/components/Newline.js +0 -36
- package/dist/ink/components/Newline.js.map +0 -1
- package/dist/ink/components/NoSelect.d.ts +0 -20
- package/dist/ink/components/NoSelect.d.ts.map +0 -1
- package/dist/ink/components/NoSelect.js +0 -63
- package/dist/ink/components/NoSelect.js.map +0 -1
- package/dist/ink/components/RawAnsi.d.ts +0 -17
- package/dist/ink/components/RawAnsi.d.ts.map +0 -1
- package/dist/ink/components/RawAnsi.js +0 -52
- package/dist/ink/components/RawAnsi.js.map +0 -1
- package/dist/ink/components/Spacer.d.ts +0 -6
- package/dist/ink/components/Spacer.d.ts.map +0 -1
- package/dist/ink/components/Spacer.js +0 -26
- package/dist/ink/components/Spacer.js.map +0 -1
- package/dist/ink/components/StdinContext.d.ts +0 -28
- package/dist/ink/components/StdinContext.d.ts.map +0 -1
- package/dist/ink/components/StdinContext.js +0 -19
- package/dist/ink/components/StdinContext.js.map +0 -1
- package/dist/ink/components/TerminalFocusContext.d.ts +0 -10
- package/dist/ink/components/TerminalFocusContext.d.ts.map +0 -1
- package/dist/ink/components/TerminalFocusContext.js +0 -81
- package/dist/ink/components/TerminalFocusContext.js.map +0 -1
- package/dist/ink/components/TerminalSizeContext.d.ts +0 -6
- package/dist/ink/components/TerminalSizeContext.d.ts.map +0 -1
- package/dist/ink/components/TerminalSizeContext.js +0 -6
- package/dist/ink/components/TerminalSizeContext.js.map +0 -1
- package/dist/ink/components/Text.d.ts +0 -56
- package/dist/ink/components/Text.d.ts.map +0 -1
- package/dist/ink/components/Text.js +0 -201
- package/dist/ink/components/Text.js.map +0 -1
- package/dist/ink/constants.d.ts +0 -2
- package/dist/ink/constants.d.ts.map +0 -1
- package/dist/ink/constants.js +0 -6
- package/dist/ink/constants.js.map +0 -1
- package/dist/ink/devtools.d.ts +0 -3
- package/dist/ink/devtools.d.ts.map +0 -1
- package/dist/ink/devtools.js +0 -5
- package/dist/ink/devtools.js.map +0 -1
- package/dist/ink/dom.d.ts +0 -77
- package/dist/ink/dom.d.ts.map +0 -1
- package/dist/ink/dom.js +0 -322
- package/dist/ink/dom.js.map +0 -1
- package/dist/ink/events/click-event.d.ts +0 -32
- package/dist/ink/events/click-event.d.ts.map +0 -1
- package/dist/ink/events/click-event.js +0 -30
- package/dist/ink/events/click-event.js.map +0 -1
- package/dist/ink/events/dispatcher.d.ts +0 -41
- package/dist/ink/events/dispatcher.d.ts.map +0 -1
- package/dist/ink/events/dispatcher.js +0 -181
- package/dist/ink/events/dispatcher.js.map +0 -1
- package/dist/ink/events/emitter.d.ts +0 -6
- package/dist/ink/events/emitter.d.ts.map +0 -1
- package/dist/ink/events/emitter.js +0 -36
- package/dist/ink/events/emitter.js.map +0 -1
- package/dist/ink/events/event-handlers.d.ts +0 -47
- package/dist/ink/events/event-handlers.d.ts.map +0 -1
- package/dist/ink/events/event-handlers.js +0 -34
- package/dist/ink/events/event-handlers.js.map +0 -1
- package/dist/ink/events/event.d.ts +0 -6
- package/dist/ink/events/event.d.ts.map +0 -1
- package/dist/ink/events/event.js +0 -16
- package/dist/ink/events/event.js.map +0 -1
- package/dist/ink/events/focus-event.d.ts +0 -14
- package/dist/ink/events/focus-event.d.ts.map +0 -1
- package/dist/ink/events/focus-event.js +0 -20
- package/dist/ink/events/focus-event.js.map +0 -1
- package/dist/ink/events/input-event.d.ts +0 -31
- package/dist/ink/events/input-event.d.ts.map +0 -1
- package/dist/ink/events/input-event.js +0 -163
- package/dist/ink/events/input-event.js.map +0 -1
- package/dist/ink/events/keyboard-event.d.ts +0 -20
- package/dist/ink/events/keyboard-event.d.ts.map +0 -1
- package/dist/ink/events/keyboard-event.js +0 -44
- package/dist/ink/events/keyboard-event.js.map +0 -1
- package/dist/ink/events/terminal-event.d.ts +0 -55
- package/dist/ink/events/terminal-event.d.ts.map +0 -1
- package/dist/ink/events/terminal-event.js +0 -79
- package/dist/ink/events/terminal-event.js.map +0 -1
- package/dist/ink/events/terminal-focus-event.d.ts +0 -14
- package/dist/ink/events/terminal-focus-event.d.ts.map +0 -1
- package/dist/ink/events/terminal-focus-event.js +0 -19
- package/dist/ink/events/terminal-focus-event.js.map +0 -1
- package/dist/ink/focus.d.ts +0 -44
- package/dist/ink/focus.d.ts.map +0 -1
- package/dist/ink/focus.js +0 -164
- package/dist/ink/focus.js.map +0 -1
- package/dist/ink/frame.d.ts +0 -95
- package/dist/ink/frame.d.ts.map +0 -1
- package/dist/ink/frame.js +0 -35
- package/dist/ink/frame.js.map +0 -1
- package/dist/ink/get-max-width.d.ts +0 -18
- package/dist/ink/get-max-width.d.ts.map +0 -1
- package/dist/ink/get-max-width.js +0 -26
- package/dist/ink/get-max-width.js.map +0 -1
- package/dist/ink/hit-test.d.ts +0 -34
- package/dist/ink/hit-test.d.ts.map +0 -1
- package/dist/ink/hit-test.js +0 -119
- package/dist/ink/hit-test.js.map +0 -1
- package/dist/ink/hooks/use-animation-frame.d.ts +0 -27
- package/dist/ink/hooks/use-animation-frame.d.ts.map +0 -1
- package/dist/ink/hooks/use-animation-frame.js +0 -52
- package/dist/ink/hooks/use-animation-frame.js.map +0 -1
- package/dist/ink/hooks/use-app.d.ts +0 -6
- package/dist/ink/hooks/use-app.d.ts.map +0 -1
- package/dist/ink/hooks/use-app.js +0 -13
- package/dist/ink/hooks/use-app.js.map +0 -1
- package/dist/ink/hooks/use-declared-cursor.d.ts +0 -27
- package/dist/ink/hooks/use-declared-cursor.d.ts.map +0 -1
- package/dist/ink/hooks/use-declared-cursor.js +0 -67
- package/dist/ink/hooks/use-declared-cursor.js.map +0 -1
- package/dist/ink/hooks/use-input.d.ts +0 -38
- package/dist/ink/hooks/use-input.d.ts.map +0 -1
- package/dist/ink/hooks/use-input.js +0 -86
- package/dist/ink/hooks/use-input.js.map +0 -1
- package/dist/ink/hooks/use-interval.d.ts +0 -19
- package/dist/ink/hooks/use-interval.d.ts.map +0 -1
- package/dist/ink/hooks/use-interval.js +0 -59
- package/dist/ink/hooks/use-interval.js.map +0 -1
- package/dist/ink/hooks/use-search-highlight.d.ts +0 -31
- package/dist/ink/hooks/use-search-highlight.d.ts.map +0 -1
- package/dist/ink/hooks/use-search-highlight.js +0 -39
- package/dist/ink/hooks/use-search-highlight.js.map +0 -1
- package/dist/ink/hooks/use-selection.d.ts +0 -40
- package/dist/ink/hooks/use-selection.d.ts.map +0 -1
- package/dist/ink/hooks/use-selection.js +0 -68
- package/dist/ink/hooks/use-selection.js.map +0 -1
- package/dist/ink/hooks/use-stdin.d.ts +0 -6
- package/dist/ink/hooks/use-stdin.d.ts.map +0 -1
- package/dist/ink/hooks/use-stdin.js +0 -13
- package/dist/ink/hooks/use-stdin.js.map +0 -1
- package/dist/ink/hooks/use-tab-status.d.ts +0 -14
- package/dist/ink/hooks/use-tab-status.d.ts.map +0 -1
- package/dist/ink/hooks/use-tab-status.js +0 -61
- package/dist/ink/hooks/use-tab-status.js.map +0 -1
- package/dist/ink/hooks/use-terminal-focus.d.ts +0 -11
- package/dist/ink/hooks/use-terminal-focus.d.ts.map +0 -1
- package/dist/ink/hooks/use-terminal-focus.js +0 -22
- package/dist/ink/hooks/use-terminal-focus.js.map +0 -1
- package/dist/ink/hooks/use-terminal-title.d.ts +0 -13
- package/dist/ink/hooks/use-terminal-title.d.ts.map +0 -1
- package/dist/ink/hooks/use-terminal-title.js +0 -36
- package/dist/ink/hooks/use-terminal-title.js.map +0 -1
- package/dist/ink/hooks/use-terminal-viewport.d.ts +0 -30
- package/dist/ink/hooks/use-terminal-viewport.d.ts.map +0 -1
- package/dist/ink/hooks/use-terminal-viewport.js +0 -81
- package/dist/ink/hooks/use-terminal-viewport.js.map +0 -1
- package/dist/ink/ink.d.ts +0 -371
- package/dist/ink/ink.d.ts.map +0 -1
- package/dist/ink/ink.js +0 -1686
- package/dist/ink/ink.js.map +0 -1
- package/dist/ink/instances.d.ts +0 -4
- package/dist/ink/instances.d.ts.map +0 -1
- package/dist/ink/instances.js +0 -10
- package/dist/ink/instances.js.map +0 -1
- package/dist/ink/line-width-cache.d.ts +0 -2
- package/dist/ink/line-width-cache.d.ts.map +0 -1
- package/dist/ink/line-width-cache.js +0 -23
- package/dist/ink/line-width-cache.js.map +0 -1
- package/dist/ink/log-update.d.ts +0 -18
- package/dist/ink/log-update.d.ts.map +0 -1
- package/dist/ink/log-update.js +0 -637
- package/dist/ink/log-update.js.map +0 -1
- package/dist/ink/measure-element.d.ts +0 -17
- package/dist/ink/measure-element.d.ts.map +0 -1
- package/dist/ink/measure-element.js +0 -11
- package/dist/ink/measure-element.js.map +0 -1
- package/dist/ink/measure-text.d.ts +0 -7
- package/dist/ink/measure-text.d.ts.map +0 -1
- package/dist/ink/measure-text.js +0 -38
- package/dist/ink/measure-text.js.map +0 -1
- package/dist/ink/node-cache.d.ts +0 -21
- package/dist/ink/node-cache.d.ts.map +0 -1
- package/dist/ink/node-cache.js +0 -36
- package/dist/ink/node-cache.js.map +0 -1
- package/dist/ink/optimizer.d.ts +0 -16
- package/dist/ink/optimizer.d.ts.map +0 -1
- package/dist/ink/optimizer.js +0 -85
- package/dist/ink/optimizer.js.map +0 -1
- package/dist/ink/output.d.ts +0 -120
- package/dist/ink/output.d.ts.map +0 -1
- package/dist/ink/output.js +0 -559
- package/dist/ink/output.js.map +0 -1
- package/dist/ink/parse-keypress.d.ts +0 -112
- package/dist/ink/parse-keypress.d.ts.map +0 -1
- package/dist/ink/parse-keypress.js +0 -719
- package/dist/ink/parse-keypress.js.map +0 -1
- package/dist/ink/parse-keypress.test.d.ts +0 -2
- package/dist/ink/parse-keypress.test.d.ts.map +0 -1
- package/dist/ink/parse-keypress.test.js +0 -37
- package/dist/ink/parse-keypress.test.js.map +0 -1
- package/dist/ink/reconciler.d.ts +0 -12
- package/dist/ink/reconciler.d.ts.map +0 -1
- package/dist/ink/reconciler.js +0 -456
- package/dist/ink/reconciler.js.map +0 -1
- package/dist/ink/render-border.d.ts +0 -25
- package/dist/ink/render-border.d.ts.map +0 -1
- package/dist/ink/render-border.js +0 -141
- package/dist/ink/render-border.js.map +0 -1
- package/dist/ink/render-node-to-output.d.ts +0 -46
- package/dist/ink/render-node-to-output.d.ts.map +0 -1
- package/dist/ink/render-node-to-output.js +0 -1257
- package/dist/ink/render-node-to-output.js.map +0 -1
- package/dist/ink/render-to-screen.d.ts +0 -47
- package/dist/ink/render-to-screen.d.ts.map +0 -1
- package/dist/ink/render-to-screen.js +0 -213
- package/dist/ink/render-to-screen.js.map +0 -1
- package/dist/ink/renderer.d.ts +0 -15
- package/dist/ink/renderer.d.ts.map +0 -1
- package/dist/ink/renderer.js +0 -169
- package/dist/ink/renderer.js.map +0 -1
- package/dist/ink/root.d.ts +0 -75
- package/dist/ink/root.d.ts.map +0 -1
- package/dist/ink/root.js +0 -89
- package/dist/ink/root.js.map +0 -1
- package/dist/ink/screen.d.ts +0 -270
- package/dist/ink/screen.d.ts.map +0 -1
- package/dist/ink/screen.js +0 -1194
- package/dist/ink/screen.js.map +0 -1
- package/dist/ink/searchHighlight.d.ts +0 -21
- package/dist/ink/searchHighlight.d.ts.map +0 -1
- package/dist/ink/searchHighlight.js +0 -82
- package/dist/ink/searchHighlight.js.map +0 -1
- package/dist/ink/selection.d.ts +0 -230
- package/dist/ink/selection.d.ts.map +0 -1
- package/dist/ink/selection.js +0 -814
- package/dist/ink/selection.js.map +0 -1
- package/dist/ink/squash-text-nodes.d.ts +0 -23
- package/dist/ink/squash-text-nodes.d.ts.map +0 -1
- package/dist/ink/squash-text-nodes.js +0 -60
- package/dist/ink/squash-text-nodes.js.map +0 -1
- package/dist/ink/stringWidth.d.ts +0 -2
- package/dist/ink/stringWidth.d.ts.map +0 -1
- package/dist/ink/stringWidth.js +0 -207
- package/dist/ink/stringWidth.js.map +0 -1
- package/dist/ink/styles.d.ts +0 -307
- package/dist/ink/styles.d.ts.map +0 -1
- package/dist/ink/styles.js +0 -302
- package/dist/ink/styles.js.map +0 -1
- package/dist/ink/supports-hyperlinks.d.ts +0 -14
- package/dist/ink/supports-hyperlinks.d.ts.map +0 -1
- package/dist/ink/supports-hyperlinks.js +0 -48
- package/dist/ink/supports-hyperlinks.js.map +0 -1
- package/dist/ink/tabstops.d.ts +0 -2
- package/dist/ink/tabstops.d.ts.map +0 -1
- package/dist/ink/tabstops.js +0 -43
- package/dist/ink/tabstops.js.map +0 -1
- package/dist/ink/terminal-focus-state.d.ts +0 -7
- package/dist/ink/terminal-focus-state.d.ts.map +0 -1
- package/dist/ink/terminal-focus-state.js +0 -43
- package/dist/ink/terminal-focus-state.js.map +0 -1
- package/dist/ink/terminal-querier.d.ts +0 -130
- package/dist/ink/terminal-querier.d.ts.map +0 -1
- package/dist/ink/terminal-querier.js +0 -184
- package/dist/ink/terminal-querier.js.map +0 -1
- package/dist/ink/terminal.d.ts +0 -56
- package/dist/ink/terminal.d.ts.map +0 -1
- package/dist/ink/terminal.js +0 -249
- package/dist/ink/terminal.js.map +0 -1
- package/dist/ink/termio/csi.d.ts +0 -166
- package/dist/ink/termio/csi.d.ts.map +0 -1
- package/dist/ink/termio/csi.js +0 -285
- package/dist/ink/termio/csi.js.map +0 -1
- package/dist/ink/termio/dec.d.ts +0 -38
- package/dist/ink/termio/dec.d.ts.map +0 -1
- package/dist/ink/termio/dec.js +0 -59
- package/dist/ink/termio/dec.js.map +0 -1
- package/dist/ink/termio.d.ts +0 -25
- package/dist/ink/termio.d.ts.map +0 -1
- package/dist/ink/termio.js +0 -32
- package/dist/ink/termio.js.map +0 -1
- package/dist/ink/useTerminalNotification.d.ts +0 -27
- package/dist/ink/useTerminalNotification.d.ts.map +0 -1
- package/dist/ink/useTerminalNotification.js +0 -62
- package/dist/ink/useTerminalNotification.js.map +0 -1
- package/dist/ink/warn.d.ts +0 -2
- package/dist/ink/warn.d.ts.map +0 -1
- package/dist/ink/warn.js +0 -14
- package/dist/ink/warn.js.map +0 -1
- package/dist/ink/widest-line.d.ts +0 -2
- package/dist/ink/widest-line.d.ts.map +0 -1
- package/dist/ink/widest-line.js +0 -18
- package/dist/ink/widest-line.js.map +0 -1
- package/dist/ink/wrap-text.d.ts +0 -3
- package/dist/ink/wrap-text.d.ts.map +0 -1
- package/dist/ink/wrap-text.js +0 -61
- package/dist/ink/wrap-text.js.map +0 -1
- package/dist/ink/wrapAnsi.d.ts +0 -8
- package/dist/ink/wrapAnsi.d.ts.map +0 -1
- package/dist/ink/wrapAnsi.js +0 -13
- package/dist/ink/wrapAnsi.js.map +0 -1
- package/dist/ink-ui/components/TerminalCursor.d.ts +0 -15
- package/dist/ink-ui/components/TerminalCursor.d.ts.map +0 -1
- package/dist/ink-ui/components/TerminalCursor.js +0 -49
- package/dist/ink-ui/components/TerminalCursor.js.map +0 -1
- package/dist/ink-ui/runtime/stdout.d.ts +0 -11
- package/dist/ink-ui/runtime/stdout.d.ts.map +0 -1
- package/dist/ink-ui/runtime/stdout.js +0 -82
- package/dist/ink-ui/runtime/stdout.js.map +0 -1
- package/dist/runtime/goal-coordinator.d.ts +0 -66
- package/dist/runtime/goal-coordinator.d.ts.map +0 -1
- package/dist/runtime/goal-coordinator.js +0 -200
- package/dist/runtime/goal-coordinator.js.map +0 -1
- package/dist/screens/REPL.d.ts +0 -21
- package/dist/screens/REPL.d.ts.map +0 -1
- package/dist/screens/REPL.js +0 -139
- package/dist/screens/REPL.js.map +0 -1
- package/dist/services/goal-sidecar.d.ts +0 -96
- package/dist/services/goal-sidecar.d.ts.map +0 -1
- package/dist/services/goal-sidecar.js +0 -145
- package/dist/services/goal-sidecar.js.map +0 -1
- package/dist/tools/goal.d.ts +0 -17
- package/dist/tools/goal.d.ts.map +0 -1
- package/dist/tools/goal.js +0 -191
- package/dist/tools/goal.js.map +0 -1
- package/dist/ui/ink/components/App.d.ts +0 -6
- package/dist/ui/ink/components/App.d.ts.map +0 -1
- package/dist/ui/ink/components/App.js +0 -38
- package/dist/ui/ink/components/App.js.map +0 -1
- package/dist/ui/ink/components/CommandPanel.d.ts +0 -13
- package/dist/ui/ink/components/CommandPanel.d.ts.map +0 -1
- package/dist/ui/ink/components/CommandPanel.js +0 -41
- package/dist/ui/ink/components/CommandPanel.js.map +0 -1
- package/dist/ui/ink/components/InputLine.d.ts +0 -8
- package/dist/ui/ink/components/InputLine.d.ts.map +0 -1
- package/dist/ui/ink/components/InputLine.js +0 -15
- package/dist/ui/ink/components/InputLine.js.map +0 -1
- package/dist/ui/ink/components/StatusBar.d.ts +0 -9
- package/dist/ui/ink/components/StatusBar.d.ts.map +0 -1
- package/dist/ui/ink/components/StatusBar.js +0 -18
- package/dist/ui/ink/components/StatusBar.js.map +0 -1
- package/dist/ui/ink/components/index.d.ts +0 -5
- package/dist/ui/ink/components/index.d.ts.map +0 -1
- package/dist/ui/ink/components/index.js +0 -5
- package/dist/ui/ink/components/index.js.map +0 -1
- package/dist/utils/chalk.d.ts +0 -9
- package/dist/utils/chalk.d.ts.map +0 -1
- package/dist/utils/chalk.js +0 -16
- package/dist/utils/chalk.js.map +0 -1
package/dist/tools/git.js
CHANGED
|
@@ -10,21 +10,43 @@
|
|
|
10
10
|
* - git_push: 安全推送(验证 + commit)
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.GIT_TOOLS = exports.gitPushTool = exports.gitStatusTool = void 0;
|
|
13
|
+
exports.GIT_TOOLS = exports.gitBranchTool = exports.gitLogTool = exports.gitDiffTool = exports.gitCommitTool = exports.gitPushTool = exports.gitStatusTool = void 0;
|
|
14
14
|
const tool_1 = require("../framework/tool");
|
|
15
15
|
const child_process_1 = require("child_process");
|
|
16
|
+
const path_1 = require("path");
|
|
17
|
+
function normalizeStagePath(value) {
|
|
18
|
+
if (value.length === 0 ||
|
|
19
|
+
value.includes('\0') ||
|
|
20
|
+
value.includes('\r') ||
|
|
21
|
+
value.includes('\n') ||
|
|
22
|
+
value.includes('\\') ||
|
|
23
|
+
value.startsWith('/') ||
|
|
24
|
+
value.startsWith(':') ||
|
|
25
|
+
['*', '?', '[', ']'].some(character => value.includes(character))) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const normalized = path_1.posix.normalize(value);
|
|
29
|
+
if (normalized === '.' || normalized === '..' || normalized.startsWith('../')) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return normalized;
|
|
33
|
+
}
|
|
34
|
+
function parseStagedPaths(output) {
|
|
35
|
+
return output.split('\0').filter(Boolean);
|
|
36
|
+
}
|
|
16
37
|
async function execGit(command, cwd, timeout = 30000) {
|
|
17
38
|
return execGitArgs(command.split(' '), cwd, timeout);
|
|
18
39
|
}
|
|
19
40
|
async function execGitArgs(args, cwd, timeout = 30000) {
|
|
20
|
-
return new Promise(
|
|
41
|
+
return new Promise(resolve => {
|
|
21
42
|
const workdir = cwd || process.cwd();
|
|
22
43
|
(0, child_process_1.execFile)('git', args, {
|
|
23
44
|
cwd: workdir,
|
|
24
45
|
timeout,
|
|
25
46
|
maxBuffer: 1024 * 1024,
|
|
26
47
|
}, (error, stdout, stderr) => {
|
|
27
|
-
|
|
48
|
+
// Preserve the leading status columns from `git status --porcelain`.
|
|
49
|
+
const output = stdout.toString().trimEnd();
|
|
28
50
|
const errOutput = stderr.toString().trim();
|
|
29
51
|
if (error) {
|
|
30
52
|
resolve({
|
|
@@ -36,7 +58,7 @@ async function execGitArgs(args, cwd, timeout = 30000) {
|
|
|
36
58
|
else {
|
|
37
59
|
resolve({
|
|
38
60
|
success: true,
|
|
39
|
-
output
|
|
61
|
+
output,
|
|
40
62
|
error: errOutput || undefined,
|
|
41
63
|
});
|
|
42
64
|
}
|
|
@@ -49,13 +71,13 @@ async function execGitArgs(args, cwd, timeout = 30000) {
|
|
|
49
71
|
async function checkUncommittedChanges(cwd) {
|
|
50
72
|
const statusResult = await execGit('status --porcelain', cwd);
|
|
51
73
|
if (!statusResult.success) {
|
|
52
|
-
return {
|
|
74
|
+
return { success: false, error: statusResult.error || 'unknown git status error' };
|
|
53
75
|
}
|
|
54
76
|
const files = statusResult.output
|
|
55
77
|
.split('\n')
|
|
56
78
|
.filter(line => line.trim())
|
|
57
79
|
.map(line => line.slice(3).trim()); // 去除状态码
|
|
58
|
-
return { hasChanges: files.length > 0, files };
|
|
80
|
+
return { success: true, hasChanges: files.length > 0, files };
|
|
59
81
|
}
|
|
60
82
|
/**
|
|
61
83
|
* 检查远程认证状态
|
|
@@ -99,7 +121,7 @@ exports.gitStatusTool = (0, tool_1.buildTool)({
|
|
|
99
121
|
// git status --porcelain
|
|
100
122
|
const statusResult = await execGit('status --porcelain', cwd);
|
|
101
123
|
if (!statusResult.success) {
|
|
102
|
-
return { success: false, output:
|
|
124
|
+
return { success: false, output: `git status failed: ${statusResult.error}`, error: `git status failed: ${statusResult.error}` };
|
|
103
125
|
}
|
|
104
126
|
// 解析状态
|
|
105
127
|
const lines = statusResult.output.split('\n').filter(l => l.trim());
|
|
@@ -121,12 +143,36 @@ exports.gitStatusTool = (0, tool_1.buildTool)({
|
|
|
121
143
|
}
|
|
122
144
|
}
|
|
123
145
|
}
|
|
146
|
+
// Upstream divergence is best-effort: a detached HEAD or a branch without an
|
|
147
|
+
// upstream makes `rev-list` fail, and that must never turn a successful
|
|
148
|
+
// `git status` into an error.
|
|
149
|
+
let ahead = 0;
|
|
150
|
+
let behind = 0;
|
|
151
|
+
try {
|
|
152
|
+
const upstream = await execGitArgs(['rev-list', '--count', '--left-right', '@{upstream}...HEAD'], cwd);
|
|
153
|
+
if (upstream.success && upstream.output.includes('\t')) {
|
|
154
|
+
// `--left-right` prints "<left>\t<right>" for `@{upstream}...HEAD`:
|
|
155
|
+
// left = commits in upstream but not HEAD -> we are behind
|
|
156
|
+
// right = commits in HEAD but not upstream -> we are ahead
|
|
157
|
+
const [behindCount, aheadCount] = upstream.output
|
|
158
|
+
.trim()
|
|
159
|
+
.split('\t')
|
|
160
|
+
.map(value => parseInt(value, 10) || 0);
|
|
161
|
+
behind = behindCount;
|
|
162
|
+
ahead = aheadCount;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// no upstream / detached HEAD -> leave ahead=behind=0
|
|
167
|
+
}
|
|
124
168
|
const summary = {
|
|
125
169
|
clean: lines.length === 0,
|
|
126
170
|
untracked,
|
|
127
171
|
modified,
|
|
128
172
|
staged,
|
|
129
173
|
total: lines.length,
|
|
174
|
+
ahead,
|
|
175
|
+
behind,
|
|
130
176
|
};
|
|
131
177
|
const output = JSON.stringify(summary, null, 2);
|
|
132
178
|
return {
|
|
@@ -144,15 +190,16 @@ exports.gitStatusTool = (0, tool_1.buildTool)({
|
|
|
144
190
|
// ============================================================================
|
|
145
191
|
exports.gitPushTool = (0, tool_1.buildTool)({
|
|
146
192
|
name: 'git_push',
|
|
147
|
-
description: `安全执行 git push,自动验证 git status
|
|
193
|
+
description: `安全执行 git push,自动验证 git status、显式 staging 边界和认证状态。
|
|
148
194
|
|
|
149
195
|
工作流程:
|
|
150
196
|
1. 检查 git status --porcelain(未暂存/未提交的文件)
|
|
151
|
-
2.
|
|
197
|
+
2. 仅对显式文件 paths 执行 git add -- <paths>;拒绝目录、glob/pathspec 和预暂存越界文件
|
|
152
198
|
3. git commit(如果需要)
|
|
153
|
-
4.
|
|
154
|
-
5.
|
|
155
|
-
6.
|
|
199
|
+
4. 若提交后仍有未提交文件,在任何远程写入前停止
|
|
200
|
+
5. 检查远程认证状态
|
|
201
|
+
6. git push
|
|
202
|
+
7. 验证 push 成功
|
|
156
203
|
|
|
157
204
|
Issue #18/#23 修复:不再在未验证的情况下声称成功。`,
|
|
158
205
|
parameters: {
|
|
@@ -164,7 +211,12 @@ Issue #18/#23 修复:不再在未验证的情况下声称成功。`,
|
|
|
164
211
|
},
|
|
165
212
|
add_all: {
|
|
166
213
|
type: 'boolean',
|
|
167
|
-
description: '
|
|
214
|
+
description: '已废弃且禁止;请使用 paths 显式列出要暂存的文件',
|
|
215
|
+
},
|
|
216
|
+
paths: {
|
|
217
|
+
type: 'array',
|
|
218
|
+
items: { type: 'string' },
|
|
219
|
+
description: '要暂存的精确仓库相对文件路径;存在工作区变更时必填',
|
|
168
220
|
},
|
|
169
221
|
cwd: {
|
|
170
222
|
type: 'string',
|
|
@@ -179,29 +231,164 @@ Issue #18/#23 修复:不再在未验证的情况下声称成功。`,
|
|
|
179
231
|
},
|
|
180
232
|
execute: async (args) => {
|
|
181
233
|
const message = args.message;
|
|
182
|
-
const addAll = args.add_all ??
|
|
234
|
+
const addAll = args.add_all ?? false;
|
|
235
|
+
const rawPaths = args.paths;
|
|
183
236
|
const cwd = args.cwd;
|
|
184
237
|
const verify = args.verify ?? true;
|
|
185
238
|
if (!message || typeof message !== 'string') {
|
|
186
239
|
return { success: false, output: '', error: 'git_push requires a commit message' };
|
|
187
240
|
}
|
|
241
|
+
if (addAll) {
|
|
242
|
+
return {
|
|
243
|
+
success: false,
|
|
244
|
+
output: '',
|
|
245
|
+
error: 'git_push add_all=true is disabled; provide an explicit paths allowlist',
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
if (rawPaths !== undefined && !Array.isArray(rawPaths)) {
|
|
249
|
+
return { success: false, output: '', error: 'git_push paths must be an array of strings' };
|
|
250
|
+
}
|
|
251
|
+
const paths = rawPaths ?? [];
|
|
252
|
+
if (paths.some(path => typeof path !== 'string')) {
|
|
253
|
+
return {
|
|
254
|
+
success: false,
|
|
255
|
+
output: '',
|
|
256
|
+
error: 'git_push paths must contain only strings',
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
const normalizedPaths = paths.map(normalizeStagePath);
|
|
260
|
+
if (normalizedPaths.some(path => path === null)) {
|
|
261
|
+
return {
|
|
262
|
+
success: false,
|
|
263
|
+
output: '',
|
|
264
|
+
error: 'git_push paths must be exact repository-relative files without glob or pathspec syntax',
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const stagePaths = [...new Set(normalizedPaths)];
|
|
188
268
|
const log = [];
|
|
189
269
|
// 1. 检查当前状态
|
|
190
270
|
log.push('🔍 Checking git status...');
|
|
191
271
|
const changes = await checkUncommittedChanges(cwd);
|
|
272
|
+
if (!changes.success) {
|
|
273
|
+
return {
|
|
274
|
+
success: false,
|
|
275
|
+
output: log.join('\n'),
|
|
276
|
+
error: `git status failed: ${changes.error}`,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
192
279
|
if (changes.hasChanges) {
|
|
193
280
|
log.push(` Found ${changes.files.length} uncommitted files: ${changes.files.slice(0, 5).join(', ')}${changes.files.length > 5 ? '...' : ''}`);
|
|
194
|
-
// 2.
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
281
|
+
// 2. 只暂存显式文件 allowlist;永不继承或扩大现有 staging 边界。
|
|
282
|
+
if (stagePaths.length === 0) {
|
|
283
|
+
return {
|
|
284
|
+
success: false,
|
|
285
|
+
output: log.join('\n'),
|
|
286
|
+
error: 'Uncommitted changes require an explicit file paths allowlist',
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
const expectedStagePaths = new Set(stagePaths);
|
|
290
|
+
for (const path of stagePaths) {
|
|
291
|
+
const exactPathResult = await execGitArgs(['ls-files', '--cached', '--others', '--exclude-standard', '-z', '--', path], cwd);
|
|
292
|
+
if (!exactPathResult.success) {
|
|
293
|
+
return {
|
|
294
|
+
success: false,
|
|
295
|
+
output: log.join('\n'),
|
|
296
|
+
error: `Exact staging-path verification failed for ${path}: ${exactPathResult.error}`,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
const matchingPaths = parseStagedPaths(exactPathResult.output);
|
|
300
|
+
if (matchingPaths.length !== 1 || matchingPaths[0] !== path) {
|
|
301
|
+
return {
|
|
302
|
+
success: false,
|
|
303
|
+
output: log.join('\n'),
|
|
304
|
+
error: `git_push paths must identify exact files, not directories or expanded pathspecs: ${path}`,
|
|
305
|
+
};
|
|
200
306
|
}
|
|
201
|
-
log.push(' ✓ Files added to staging');
|
|
202
307
|
}
|
|
203
|
-
|
|
204
|
-
|
|
308
|
+
const initialStagedResult = await execGitArgs(['diff', '--cached', '--name-only', '-z'], cwd);
|
|
309
|
+
if (!initialStagedResult.success) {
|
|
310
|
+
return {
|
|
311
|
+
success: false,
|
|
312
|
+
output: log.join('\n'),
|
|
313
|
+
error: `Initial staged-file verification failed: ${initialStagedResult.error}`,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
const unexpectedInitialPaths = parseStagedPaths(initialStagedResult.output).filter(path => !expectedStagePaths.has(path));
|
|
317
|
+
if (unexpectedInitialPaths.length > 0) {
|
|
318
|
+
return {
|
|
319
|
+
success: false,
|
|
320
|
+
output: log.join('\n'),
|
|
321
|
+
error: `Pre-staged files fall outside the explicit allowlist: ${unexpectedInitialPaths.join(', ')}`,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
const indexSnapshotResult = await execGitArgs(['write-tree'], cwd);
|
|
325
|
+
if (!indexSnapshotResult.success || !/^[0-9a-f]{40,64}$/.test(indexSnapshotResult.output)) {
|
|
326
|
+
return {
|
|
327
|
+
success: false,
|
|
328
|
+
output: log.join('\n'),
|
|
329
|
+
error: `Unable to snapshot the Git index before staging: ${indexSnapshotResult.error || 'invalid tree id'}`,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
const restoreIndex = async () => {
|
|
333
|
+
const result = await execGitArgs(['read-tree', indexSnapshotResult.output], cwd);
|
|
334
|
+
return result.success ? undefined : result.error || 'unknown index restore error';
|
|
335
|
+
};
|
|
336
|
+
log.push(`📦 Staging ${stagePaths.length} explicit file(s)...`);
|
|
337
|
+
const addResult = await execGitArgs(['add', '--', ...stagePaths], cwd);
|
|
338
|
+
if (!addResult.success) {
|
|
339
|
+
const restoreError = await restoreIndex();
|
|
340
|
+
return {
|
|
341
|
+
success: false,
|
|
342
|
+
output: log.join('\n'),
|
|
343
|
+
error: restoreError
|
|
344
|
+
? `git add failed: ${addResult.error}; index rollback failed: ${restoreError}`
|
|
345
|
+
: `git add failed: ${addResult.error}; index restored`,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
log.push(` ✓ Staged: ${stagePaths.slice(0, 5).join(', ')}${stagePaths.length > 5 ? '...' : ''}`);
|
|
349
|
+
const stagedResult = await execGitArgs(['diff', '--cached', '--name-only', '-z'], cwd);
|
|
350
|
+
if (!stagedResult.success) {
|
|
351
|
+
const restoreError = await restoreIndex();
|
|
352
|
+
return {
|
|
353
|
+
success: false,
|
|
354
|
+
output: log.join('\n'),
|
|
355
|
+
error: restoreError
|
|
356
|
+
? `Staged-file verification failed: ${stagedResult.error}; index rollback failed: ${restoreError}`
|
|
357
|
+
: `Staged-file verification failed: ${stagedResult.error}; index restored`,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
const stagedFiles = parseStagedPaths(stagedResult.output);
|
|
361
|
+
const unexpectedStagedPaths = stagedFiles.filter(path => !expectedStagePaths.has(path));
|
|
362
|
+
const missingStagedPaths = stagePaths.filter(path => !stagedFiles.includes(path));
|
|
363
|
+
if (unexpectedStagedPaths.length > 0 || missingStagedPaths.length > 0) {
|
|
364
|
+
const restoreError = await restoreIndex();
|
|
365
|
+
return {
|
|
366
|
+
success: false,
|
|
367
|
+
output: log.join('\n'),
|
|
368
|
+
error: [
|
|
369
|
+
'Staged files do not exactly match the explicit allowlist',
|
|
370
|
+
unexpectedStagedPaths.length > 0
|
|
371
|
+
? `unexpected: ${unexpectedStagedPaths.join(', ')}`
|
|
372
|
+
: '',
|
|
373
|
+
missingStagedPaths.length > 0 ? `missing: ${missingStagedPaths.join(', ')}` : '',
|
|
374
|
+
restoreError ? `index rollback failed: ${restoreError}` : 'index restored',
|
|
375
|
+
]
|
|
376
|
+
.filter(Boolean)
|
|
377
|
+
.join('; '),
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
log.push(` ✓ Verified ${stagedFiles.length} staged file(s)`);
|
|
381
|
+
const preCommitHead = await execGitArgs(['rev-parse', 'HEAD'], cwd);
|
|
382
|
+
if (!preCommitHead.success || !/^[0-9a-f]{40,64}$/.test(preCommitHead.output)) {
|
|
383
|
+
const restoreError = await restoreIndex();
|
|
384
|
+
return {
|
|
385
|
+
success: false,
|
|
386
|
+
output: log.join('\n'),
|
|
387
|
+
error: [
|
|
388
|
+
`Unable to snapshot HEAD before commit: ${preCommitHead.error || 'invalid commit id'}`,
|
|
389
|
+
restoreError ? `index rollback failed: ${restoreError}` : 'index restored',
|
|
390
|
+
].join('; '),
|
|
391
|
+
};
|
|
205
392
|
}
|
|
206
393
|
// 3. git commit
|
|
207
394
|
log.push(`📝 Committing with message: "${message.slice(0, 50)}..."`);
|
|
@@ -212,12 +399,46 @@ Issue #18/#23 修复:不再在未验证的情况下声称成功。`,
|
|
|
212
399
|
log.push(' ⚠ Nothing new to commit');
|
|
213
400
|
}
|
|
214
401
|
else {
|
|
215
|
-
|
|
402
|
+
const postFailureHead = await execGitArgs(['rev-parse', 'HEAD'], cwd);
|
|
403
|
+
const restoreError = await restoreIndex();
|
|
404
|
+
const headChanged = postFailureHead.success && postFailureHead.output !== preCommitHead.output;
|
|
405
|
+
const headStatus = !postFailureHead.success
|
|
406
|
+
? `HEAD verification failed: ${postFailureHead.error || 'unknown error'}`
|
|
407
|
+
: headChanged
|
|
408
|
+
? `HEAD changed unexpectedly from ${preCommitHead.output} to ${postFailureHead.output}; manual recovery required`
|
|
409
|
+
: undefined;
|
|
410
|
+
return {
|
|
411
|
+
success: false,
|
|
412
|
+
output: log.join('\n'),
|
|
413
|
+
error: [
|
|
414
|
+
`git commit failed: ${commitResult.error}`,
|
|
415
|
+
restoreError ? `index rollback failed: ${restoreError}` : 'index restored',
|
|
416
|
+
headStatus,
|
|
417
|
+
]
|
|
418
|
+
.filter(Boolean)
|
|
419
|
+
.join('; '),
|
|
420
|
+
};
|
|
216
421
|
}
|
|
217
422
|
}
|
|
218
423
|
else {
|
|
219
424
|
log.push(' ✓ Commit successful');
|
|
220
425
|
}
|
|
426
|
+
const postCommitChanges = await checkUncommittedChanges(cwd);
|
|
427
|
+
if (!postCommitChanges.success) {
|
|
428
|
+
return {
|
|
429
|
+
success: false,
|
|
430
|
+
output: log.join('\n'),
|
|
431
|
+
error: `Post-commit git status failed: ${postCommitChanges.error}`,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
if (postCommitChanges.hasChanges) {
|
|
435
|
+
log.push(` ⚠ ${postCommitChanges.files.length} file(s) remain outside the committed boundary`);
|
|
436
|
+
return {
|
|
437
|
+
success: false,
|
|
438
|
+
output: log.join('\n'),
|
|
439
|
+
error: 'Commit created but push was not attempted because the working tree is not clean',
|
|
440
|
+
};
|
|
441
|
+
}
|
|
221
442
|
}
|
|
222
443
|
else {
|
|
223
444
|
log.push(' ✓ Working directory clean, no changes to commit');
|
|
@@ -230,7 +451,7 @@ Issue #18/#23 修复:不再在未验证的情况下声称成功。`,
|
|
|
230
451
|
return {
|
|
231
452
|
success: false,
|
|
232
453
|
output: log.join('\n'),
|
|
233
|
-
error: auth.error || 'Remote authentication failed - please configure git credentials'
|
|
454
|
+
error: auth.error || 'Remote authentication failed - please configure git credentials',
|
|
234
455
|
};
|
|
235
456
|
}
|
|
236
457
|
log.push(' ✓ Authentication verified');
|
|
@@ -239,14 +460,39 @@ Issue #18/#23 修复:不再在未验证的情况下声称成功。`,
|
|
|
239
460
|
log.push('🚀 Pushing to remote...');
|
|
240
461
|
const pushResult = await execGit('push', cwd, 60000); // 60s timeout
|
|
241
462
|
if (!pushResult.success) {
|
|
242
|
-
return {
|
|
463
|
+
return {
|
|
464
|
+
success: false,
|
|
465
|
+
output: log.join('\n'),
|
|
466
|
+
error: `git push failed: ${pushResult.error}`,
|
|
467
|
+
};
|
|
243
468
|
}
|
|
244
469
|
log.push(' ✓ Push completed');
|
|
245
470
|
// 6. 验证最终状态(v0.1.11 增强)
|
|
246
471
|
log.push('✅ Verifying final status...');
|
|
247
472
|
const finalChanges = await checkUncommittedChanges(cwd);
|
|
473
|
+
if (!finalChanges.success) {
|
|
474
|
+
return {
|
|
475
|
+
success: false,
|
|
476
|
+
output: log.join('\n'),
|
|
477
|
+
error: `Final git status failed: ${finalChanges.error}`,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
248
480
|
const logResult = await execGit('log --oneline -1', cwd);
|
|
481
|
+
if (!logResult.success) {
|
|
482
|
+
return {
|
|
483
|
+
success: false,
|
|
484
|
+
output: log.join('\n'),
|
|
485
|
+
error: `Final git log failed: ${logResult.error}`,
|
|
486
|
+
};
|
|
487
|
+
}
|
|
249
488
|
const untrackedResult = await execGit('status --short', cwd);
|
|
489
|
+
if (!untrackedResult.success) {
|
|
490
|
+
return {
|
|
491
|
+
success: false,
|
|
492
|
+
output: log.join('\n'),
|
|
493
|
+
error: `Final git status --short failed: ${untrackedResult.error}`,
|
|
494
|
+
};
|
|
495
|
+
}
|
|
250
496
|
// v0.1.11: 检查是否有未追踪文件(?? 状态)
|
|
251
497
|
const untrackedFiles = untrackedResult.output
|
|
252
498
|
.split('\n')
|
|
@@ -266,8 +512,29 @@ Issue #18/#23 修复:不再在未验证的情况下声称成功。`,
|
|
|
266
512
|
error: 'Push completed but some files remain uncommitted - check git status',
|
|
267
513
|
};
|
|
268
514
|
}
|
|
515
|
+
const branchResult = await execGitArgs(['branch', '--show-current'], cwd);
|
|
516
|
+
if (!branchResult.success || !branchResult.output.trim()) {
|
|
517
|
+
return {
|
|
518
|
+
success: false,
|
|
519
|
+
output: log.join('\n'),
|
|
520
|
+
error: `Push completed but current branch verification failed: ${branchResult.error || 'empty branch'}`,
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
const branch = branchResult.output.trim();
|
|
524
|
+
const remoteResult = await execGitArgs(['config', '--get', `branch.${branch}.remote`], cwd);
|
|
525
|
+
if (!remoteResult.success || !remoteResult.output.trim()) {
|
|
526
|
+
return {
|
|
527
|
+
success: false,
|
|
528
|
+
output: log.join('\n'),
|
|
529
|
+
error: `Push completed but upstream remote verification failed: ${remoteResult.error || 'missing branch remote'}`,
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
const remote = remoteResult.output.trim();
|
|
533
|
+
const latestCommit = logResult.output.split('\n')[0];
|
|
269
534
|
log.push(` ✓ Working directory clean`);
|
|
270
|
-
log.push(` ✓
|
|
535
|
+
log.push(` ✓ Pushed branch: ${branch}`);
|
|
536
|
+
log.push(` ✓ Remote: ${remote}`);
|
|
537
|
+
log.push(` ✓ Latest commit: ${latestCommit}`);
|
|
271
538
|
return {
|
|
272
539
|
success: true,
|
|
273
540
|
output: log.join('\n'),
|
|
@@ -275,11 +542,299 @@ Issue #18/#23 修复:不再在未验证的情况下声称成功。`,
|
|
|
275
542
|
},
|
|
276
543
|
isDestructive: () => true,
|
|
277
544
|
isConcurrencySafe: () => false,
|
|
278
|
-
checkPermissions:
|
|
279
|
-
|
|
545
|
+
checkPermissions: args => ({
|
|
546
|
+
behavior: 'ask',
|
|
547
|
+
reason: Array.isArray(args.paths) && args.paths.length > 0
|
|
548
|
+
? `git push will stage ${args.paths.length} explicit path(s), commit, and modify the remote repository`
|
|
549
|
+
: 'git push will modify the remote repository and refuses uncommitted changes without explicit paths',
|
|
550
|
+
}),
|
|
551
|
+
userFacingName: args => `Git Push: ${args.message?.slice(0, 30)}`,
|
|
552
|
+
});
|
|
553
|
+
// ============================================================================
|
|
554
|
+
// git_commit 工具
|
|
555
|
+
// ============================================================================
|
|
556
|
+
exports.gitCommitTool = (0, tool_1.buildTool)({
|
|
557
|
+
name: 'git_commit',
|
|
558
|
+
description: `提交工作区变更到本地仓库。
|
|
559
|
+
|
|
560
|
+
工作流程:
|
|
561
|
+
1. 检查 git status --porcelain
|
|
562
|
+
2. 仅对显式 paths 暂存(或 all=true 暂存全部已追踪变更)
|
|
563
|
+
3. git commit -m <message>
|
|
564
|
+
4. 验证 commit 成功
|
|
565
|
+
|
|
566
|
+
安全:要求明确 message;拒绝盲目暂存未受控文件。`,
|
|
567
|
+
parameters: {
|
|
568
|
+
type: 'object',
|
|
569
|
+
properties: {
|
|
570
|
+
message: { type: 'string', description: 'Commit message(必填)' },
|
|
571
|
+
paths: {
|
|
572
|
+
type: 'array',
|
|
573
|
+
items: { type: 'string' },
|
|
574
|
+
description: '要暂存的精确仓库相对文件路径;与 all 互斥',
|
|
575
|
+
},
|
|
576
|
+
all: {
|
|
577
|
+
type: 'boolean',
|
|
578
|
+
description: '暂存所有已追踪文件的变更(不含未追踪文件)',
|
|
579
|
+
},
|
|
580
|
+
cwd: { type: 'string', description: '工作目录(可选)' },
|
|
581
|
+
},
|
|
582
|
+
required: ['message'],
|
|
583
|
+
},
|
|
584
|
+
execute: async (args) => {
|
|
585
|
+
const message = args.message;
|
|
586
|
+
const rawPaths = args.paths;
|
|
587
|
+
const all = args.all ?? false;
|
|
588
|
+
const cwd = args.cwd;
|
|
589
|
+
if (!message || typeof message !== 'string') {
|
|
590
|
+
return {
|
|
591
|
+
success: false,
|
|
592
|
+
output: 'git_commit requires a commit message',
|
|
593
|
+
error: 'git_commit requires a commit message',
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
if (rawPaths !== undefined && !Array.isArray(rawPaths)) {
|
|
597
|
+
return {
|
|
598
|
+
success: false,
|
|
599
|
+
output: 'git_commit paths must be an array of strings',
|
|
600
|
+
error: 'git_commit paths must be an array of strings',
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
const paths = rawPaths ?? [];
|
|
604
|
+
if (paths.some(item => typeof item !== 'string')) {
|
|
605
|
+
return {
|
|
606
|
+
success: false,
|
|
607
|
+
output: 'git_commit paths must contain only strings',
|
|
608
|
+
error: 'git_commit paths must contain only strings',
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
const normalized = paths.map(normalizeStagePath);
|
|
612
|
+
if (normalized.some(item => item === null)) {
|
|
613
|
+
return {
|
|
614
|
+
success: false,
|
|
615
|
+
output: 'git_commit paths must be exact repository-relative files without glob or pathspec syntax',
|
|
616
|
+
error: 'git_commit paths must be exact repository-relative files without glob or pathspec syntax',
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
const stagePaths = [...new Set(normalized)];
|
|
620
|
+
const log = [];
|
|
621
|
+
log.push('🔍 Checking git status...');
|
|
622
|
+
const changes = await checkUncommittedChanges(cwd);
|
|
623
|
+
if (!changes.success) {
|
|
624
|
+
return { success: false, output: log.join('\n'), error: `git status failed: ${changes.error}` };
|
|
625
|
+
}
|
|
626
|
+
if (!changes.hasChanges && stagePaths.length === 0 && !all) {
|
|
627
|
+
return { success: true, output: '✓ Working directory clean, nothing to commit' };
|
|
628
|
+
}
|
|
629
|
+
if (all) {
|
|
630
|
+
log.push('📦 Staging all tracked changes...');
|
|
631
|
+
const addResult = await execGit('add -u', cwd);
|
|
632
|
+
if (!addResult.success) {
|
|
633
|
+
return { success: false, output: log.join('\n'), error: `git add -u failed: ${addResult.error}` };
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
else if (stagePaths.length > 0) {
|
|
637
|
+
log.push(`📦 Staging ${stagePaths.length} explicit path(s)...`);
|
|
638
|
+
const addResult = await execGitArgs(['add', '--', ...stagePaths], cwd);
|
|
639
|
+
if (!addResult.success) {
|
|
640
|
+
return { success: false, output: log.join('\n'), error: `git add failed: ${addResult.error}` };
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
return {
|
|
645
|
+
success: false,
|
|
646
|
+
output: log.join('\n'),
|
|
647
|
+
error: 'No changes staged: provide paths or set all=true',
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
log.push(`📝 Committing: "${message.slice(0, 50)}..."`);
|
|
651
|
+
const commitResult = await execGitArgs(['commit', '-m', message], cwd);
|
|
652
|
+
if (!commitResult.success) {
|
|
653
|
+
await execGit('reset', cwd);
|
|
654
|
+
if (commitResult.output.includes('nothing to commit')) {
|
|
655
|
+
return { success: true, output: log.join('\n') + '\n ⚠ Nothing new to commit' };
|
|
656
|
+
}
|
|
657
|
+
return { success: false, output: log.join('\n'), error: `git commit failed: ${commitResult.error}` };
|
|
658
|
+
}
|
|
659
|
+
log.push(' ✓ Commit successful');
|
|
660
|
+
const logResult = await execGit('log --oneline -1', cwd);
|
|
661
|
+
if (logResult.success)
|
|
662
|
+
log.push(` ✓ Latest commit: ${logResult.output.split('\n')[0]}`);
|
|
663
|
+
return { success: true, output: log.join('\n') };
|
|
664
|
+
},
|
|
665
|
+
isDestructive: () => false,
|
|
666
|
+
isConcurrencySafe: () => false,
|
|
667
|
+
checkPermissions: () => ({
|
|
668
|
+
behavior: 'ask',
|
|
669
|
+
reason: 'git commit will create a new commit in the local repository',
|
|
670
|
+
}),
|
|
671
|
+
userFacingName: args => `Git Commit: ${args.message?.slice(0, 30)}`,
|
|
672
|
+
});
|
|
673
|
+
// ============================================================================
|
|
674
|
+
// git_diff 工具
|
|
675
|
+
// ============================================================================
|
|
676
|
+
exports.gitDiffTool = (0, tool_1.buildTool)({
|
|
677
|
+
name: 'git_diff',
|
|
678
|
+
description: '显示 Git 差异。默认工作区 vs 暂存区;staged=true 显示已暂存 vs HEAD;可指定 paths。',
|
|
679
|
+
parameters: {
|
|
680
|
+
type: 'object',
|
|
681
|
+
properties: {
|
|
682
|
+
staged: { type: 'boolean', description: '显示已暂存变更(vs HEAD),默认 false' },
|
|
683
|
+
stat: { type: 'boolean', description: '仅显示统计摘要(默认 false)' },
|
|
684
|
+
paths: { type: 'array', items: { type: 'string' }, description: '限定路径(可选)' },
|
|
685
|
+
cwd: { type: 'string', description: '工作目录(可选)' },
|
|
686
|
+
},
|
|
687
|
+
required: [],
|
|
688
|
+
},
|
|
689
|
+
execute: async (args) => {
|
|
690
|
+
const staged = args.staged ?? false;
|
|
691
|
+
const stat = args.stat ?? false;
|
|
692
|
+
const rawPaths = args.paths;
|
|
693
|
+
const cwd = args.cwd;
|
|
694
|
+
const paths = Array.isArray(rawPaths) ? rawPaths.map(String) : [];
|
|
695
|
+
const cmd = ['diff', '--no-color'];
|
|
696
|
+
if (stat)
|
|
697
|
+
cmd.push('--stat');
|
|
698
|
+
if (staged)
|
|
699
|
+
cmd.push('--cached');
|
|
700
|
+
if (paths.length)
|
|
701
|
+
cmd.push('--', ...paths);
|
|
702
|
+
const result = await execGitArgs(cmd, cwd, 60000);
|
|
703
|
+
if (!result.success) {
|
|
704
|
+
return { success: false, output: `git diff failed: ${result.error}`, error: `git diff failed: ${result.error}` };
|
|
705
|
+
}
|
|
706
|
+
const MAX = 20000;
|
|
707
|
+
const out = result.output.length > MAX
|
|
708
|
+
? `${result.output.slice(0, MAX)}\n… (truncated, ${result.output.length} chars total)`
|
|
709
|
+
: result.output;
|
|
710
|
+
return { success: true, output: out || 'No differences' };
|
|
711
|
+
},
|
|
712
|
+
isReadOnly: () => true,
|
|
713
|
+
isConcurrencySafe: () => true,
|
|
714
|
+
checkPermissions: () => ({ behavior: 'allow' }),
|
|
715
|
+
userFacingName: () => 'Git Diff',
|
|
716
|
+
});
|
|
717
|
+
// ============================================================================
|
|
718
|
+
// git_log 工具
|
|
719
|
+
// ============================================================================
|
|
720
|
+
exports.gitLogTool = (0, tool_1.buildTool)({
|
|
721
|
+
name: 'git_log',
|
|
722
|
+
description: '显示提交历史。可指定条数与格式。',
|
|
723
|
+
parameters: {
|
|
724
|
+
type: 'object',
|
|
725
|
+
properties: {
|
|
726
|
+
max_count: { type: 'number', description: '返回的最大提交数(默认 20,上限 200)' },
|
|
727
|
+
oneline: { type: 'boolean', description: '单行精简格式(默认 true)' },
|
|
728
|
+
cwd: { type: 'string', description: '工作目录(可选)' },
|
|
729
|
+
},
|
|
730
|
+
required: [],
|
|
731
|
+
},
|
|
732
|
+
execute: async (args) => {
|
|
733
|
+
const maxCount = typeof args.max_count === 'number' ? Math.min(Math.max(args.max_count, 1), 200) : 20;
|
|
734
|
+
const oneline = args.oneline ?? true;
|
|
735
|
+
const cwd = args.cwd;
|
|
736
|
+
const fmt = oneline ? '%h %s (%an, %ar)' : '%H%nAuthor: %an <%ae>%nDate: %ad%n%n%B';
|
|
737
|
+
const cmd = ['log', `--max-count=${maxCount}`, `--pretty=format:${fmt}`, '--no-color'];
|
|
738
|
+
if (!oneline)
|
|
739
|
+
cmd.push('--date=iso');
|
|
740
|
+
const result = await execGitArgs(cmd, cwd, 30000);
|
|
741
|
+
if (!result.success) {
|
|
742
|
+
return { success: false, output: `git log failed: ${result.error}`, error: `git log failed: ${result.error}` };
|
|
743
|
+
}
|
|
744
|
+
return { success: true, output: result.output || 'No commits' };
|
|
745
|
+
},
|
|
746
|
+
isReadOnly: () => true,
|
|
747
|
+
isConcurrencySafe: () => true,
|
|
748
|
+
checkPermissions: () => ({ behavior: 'allow' }),
|
|
749
|
+
userFacingName: () => 'Git Log',
|
|
750
|
+
});
|
|
751
|
+
// ============================================================================
|
|
752
|
+
// git_branch 工具
|
|
753
|
+
// ============================================================================
|
|
754
|
+
exports.gitBranchTool = (0, tool_1.buildTool)({
|
|
755
|
+
name: 'git_branch',
|
|
756
|
+
description: `分支操作。
|
|
757
|
+
|
|
758
|
+
action:
|
|
759
|
+
- list(默认): 列出本地分支,标记当前分支(*)与上游跟踪
|
|
760
|
+
- create: 基于当前 HEAD 创建新分支(不切换)
|
|
761
|
+
- switch: 切换到已有分支
|
|
762
|
+
- delete: 删除本地分支(需 force 才允许未合并删除)`,
|
|
763
|
+
parameters: {
|
|
764
|
+
type: 'object',
|
|
765
|
+
properties: {
|
|
766
|
+
action: {
|
|
767
|
+
type: 'string',
|
|
768
|
+
enum: ['list', 'create', 'switch', 'delete'],
|
|
769
|
+
description: '操作类型(默认 list)',
|
|
770
|
+
},
|
|
771
|
+
name: { type: 'string', description: '分支名(create/switch/delete 必填)' },
|
|
772
|
+
force: { type: 'boolean', description: 'delete 时允许删除未合并分支(默认 false)' },
|
|
773
|
+
cwd: { type: 'string', description: '工作目录(可选)' },
|
|
774
|
+
},
|
|
775
|
+
required: [],
|
|
776
|
+
},
|
|
777
|
+
execute: async (args) => {
|
|
778
|
+
const action = args.action ?? 'list';
|
|
779
|
+
const name = args.name;
|
|
780
|
+
const force = args.force ?? false;
|
|
781
|
+
const cwd = args.cwd;
|
|
782
|
+
const log = [];
|
|
783
|
+
if (action === 'list') {
|
|
784
|
+
const result = await execGit('branch -vv', cwd);
|
|
785
|
+
if (!result.success) {
|
|
786
|
+
return { success: false, output: `git branch -vv failed: ${result.error}`, error: `git branch -vv failed: ${result.error}` };
|
|
787
|
+
}
|
|
788
|
+
return { success: true, output: result.output || 'No branches' };
|
|
789
|
+
}
|
|
790
|
+
if (!name || typeof name !== 'string') {
|
|
791
|
+
return { success: false, output: '', error: `git_branch ${action} requires a branch name` };
|
|
792
|
+
}
|
|
793
|
+
if (action === 'create') {
|
|
794
|
+
const result = await execGitArgs(['branch', name], cwd);
|
|
795
|
+
if (!result.success) {
|
|
796
|
+
return { success: false, output: log.join('\n'), error: `git branch create failed: ${result.error}` };
|
|
797
|
+
}
|
|
798
|
+
log.push(`✓ Created branch ${name}`);
|
|
799
|
+
return { success: true, output: log.join('\n') };
|
|
800
|
+
}
|
|
801
|
+
if (action === 'switch') {
|
|
802
|
+
const result = await execGitArgs(['checkout', name], cwd);
|
|
803
|
+
if (!result.success) {
|
|
804
|
+
return { success: false, output: log.join('\n'), error: `git checkout failed: ${result.error}` };
|
|
805
|
+
}
|
|
806
|
+
log.push(`✓ Switched to ${name}`);
|
|
807
|
+
return { success: true, output: log.join('\n') };
|
|
808
|
+
}
|
|
809
|
+
if (action === 'delete') {
|
|
810
|
+
const result = await execGitArgs(force ? ['branch', '-D', name] : ['branch', '-d', name], cwd);
|
|
811
|
+
if (!result.success) {
|
|
812
|
+
return { success: false, output: log.join('\n'), error: `git branch delete failed: ${result.error}` };
|
|
813
|
+
}
|
|
814
|
+
log.push(`✓ Deleted branch ${name}`);
|
|
815
|
+
return { success: true, output: log.join('\n') };
|
|
816
|
+
}
|
|
817
|
+
return { success: false, output: `Unknown git_branch action: ${action}`, error: `Unknown git_branch action: ${action}` };
|
|
818
|
+
},
|
|
819
|
+
isDestructive: () => false,
|
|
820
|
+
isConcurrencySafe: () => false,
|
|
821
|
+
checkPermissions: args => {
|
|
822
|
+
const action = args.action ?? 'list';
|
|
823
|
+
if (action === 'list')
|
|
824
|
+
return { behavior: 'allow' };
|
|
825
|
+
return { behavior: 'ask', reason: `git branch ${action} will modify local branch state` };
|
|
826
|
+
},
|
|
827
|
+
userFacingName: args => `Git Branch: ${args.action ?? 'list'}`,
|
|
280
828
|
});
|
|
281
829
|
// ============================================================================
|
|
282
830
|
// 导出
|
|
283
831
|
// ============================================================================
|
|
284
|
-
exports.GIT_TOOLS = [
|
|
832
|
+
exports.GIT_TOOLS = [
|
|
833
|
+
exports.gitStatusTool,
|
|
834
|
+
exports.gitPushTool,
|
|
835
|
+
exports.gitCommitTool,
|
|
836
|
+
exports.gitDiffTool,
|
|
837
|
+
exports.gitLogTool,
|
|
838
|
+
exports.gitBranchTool,
|
|
839
|
+
];
|
|
285
840
|
//# sourceMappingURL=git.js.map
|