@getpaseo/server 0.1.61 → 0.1.63
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 +4 -0
- package/dist/server/client/daemon-client-runtime-metrics.d.ts +6 -6
- package/dist/server/client/daemon-client-runtime-metrics.d.ts.map +1 -1
- package/dist/server/client/daemon-client-transport-types.d.ts +13 -13
- package/dist/server/client/daemon-client-transport-types.d.ts.map +1 -1
- package/dist/server/client/daemon-client-websocket-transport.d.ts +1 -1
- package/dist/server/client/daemon-client-websocket-transport.d.ts.map +1 -1
- package/dist/server/client/daemon-client-websocket-transport.js +5 -4
- package/dist/server/client/daemon-client-websocket-transport.js.map +1 -1
- package/dist/server/client/daemon-client.d.ts +59 -37
- package/dist/server/client/daemon-client.d.ts.map +1 -1
- package/dist/server/client/daemon-client.js +62 -17
- package/dist/server/client/daemon-client.js.map +1 -1
- package/dist/server/server/agent/agent-loading.d.ts.map +1 -1
- package/dist/server/server/agent/agent-loading.js +5 -3
- package/dist/server/server/agent/agent-loading.js.map +1 -1
- package/dist/server/server/agent/agent-manager.d.ts +45 -19
- package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
- package/dist/server/server/agent/agent-manager.js +393 -290
- package/dist/server/server/agent/agent-manager.js.map +1 -1
- package/dist/server/server/agent/agent-metadata-generator.d.ts +6 -6
- package/dist/server/server/agent/agent-metadata-generator.d.ts.map +1 -1
- package/dist/server/server/agent/agent-metadata-generator.js +46 -38
- package/dist/server/server/agent/agent-metadata-generator.js.map +1 -1
- package/dist/server/server/agent/agent-projections.d.ts +4 -6
- package/dist/server/server/agent/agent-projections.d.ts.map +1 -1
- package/dist/server/server/agent/agent-projections.js +59 -65
- package/dist/server/server/agent/agent-projections.js.map +1 -1
- package/dist/server/server/agent/agent-response-loop.d.ts +4 -4
- package/dist/server/server/agent/agent-response-loop.d.ts.map +1 -1
- package/dist/server/server/agent/agent-response-loop.js +58 -45
- package/dist/server/server/agent/agent-response-loop.js.map +1 -1
- package/dist/server/server/agent/agent-sdk-types.d.ts +43 -40
- package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
- package/dist/server/server/agent/agent-sdk-types.js.map +1 -1
- package/dist/server/server/agent/agent-storage.d.ts +2 -2
- package/dist/server/server/agent/agent-storage.d.ts.map +1 -1
- package/dist/server/server/agent/agent-storage.js +29 -36
- package/dist/server/server/agent/agent-storage.js.map +1 -1
- package/dist/server/server/agent/agent-stream-coalescer.d.ts +6 -6
- package/dist/server/server/agent/agent-stream-coalescer.d.ts.map +1 -1
- package/dist/server/server/agent/agent-timeline-store-types.d.ts +10 -10
- package/dist/server/server/agent/agent-timeline-store-types.d.ts.map +1 -1
- package/dist/server/server/agent/agent-timeline-store.d.ts +2 -2
- package/dist/server/server/agent/agent-timeline-store.d.ts.map +1 -1
- package/dist/server/server/agent/agent-timeline-store.js +85 -64
- package/dist/server/server/agent/agent-timeline-store.js.map +1 -1
- package/dist/server/server/agent/mcp-server.d.ts.map +1 -1
- package/dist/server/server/agent/mcp-server.js +185 -148
- package/dist/server/server/agent/mcp-server.js.map +1 -1
- package/dist/server/server/agent/mcp-shared.d.ts +9 -2
- package/dist/server/server/agent/mcp-shared.d.ts.map +1 -1
- package/dist/server/server/agent/mcp-shared.js +2 -0
- package/dist/server/server/agent/mcp-shared.js.map +1 -1
- package/dist/server/server/agent/model-resolver.d.ts +2 -2
- package/dist/server/server/agent/model-resolver.d.ts.map +1 -1
- package/dist/server/server/agent/model-resolver.js +9 -5
- package/dist/server/server/agent/model-resolver.js.map +1 -1
- package/dist/server/server/agent/provider-launch-config.d.ts +28 -17
- package/dist/server/server/agent/provider-launch-config.d.ts.map +1 -1
- package/dist/server/server/agent/provider-launch-config.js +20 -9
- package/dist/server/server/agent/provider-launch-config.js.map +1 -1
- package/dist/server/server/agent/provider-registry.d.ts +4 -2
- package/dist/server/server/agent/provider-registry.d.ts.map +1 -1
- package/dist/server/server/agent/provider-registry.js +24 -21
- package/dist/server/server/agent/provider-registry.js.map +1 -1
- package/dist/server/server/agent/provider-snapshot-manager.d.ts +6 -5
- package/dist/server/server/agent/provider-snapshot-manager.d.ts.map +1 -1
- package/dist/server/server/agent/provider-snapshot-manager.js +40 -31
- package/dist/server/server/agent/provider-snapshot-manager.js.map +1 -1
- package/dist/server/server/agent/providers/acp-agent.d.ts +11 -12
- package/dist/server/server/agent/providers/acp-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/acp-agent.js +148 -122
- package/dist/server/server/agent/providers/acp-agent.js.map +1 -1
- package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts +2 -0
- package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude/sidechain-tracker.js +47 -45
- package/dist/server/server/agent/providers/claude/sidechain-tracker.js.map +1 -1
- package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts +2 -2
- package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude/task-notification-tool-call.js +10 -5
- package/dist/server/server/agent/providers/claude/task-notification-tool-call.js.map +1 -1
- package/dist/server/server/agent/providers/claude/tool-call-detail-parser.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js +11 -2
- package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js.map +1 -1
- package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts +2 -2
- package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude/tool-call-mapper.js +20 -13
- package/dist/server/server/agent/providers/claude/tool-call-mapper.js.map +1 -1
- package/dist/server/server/agent/providers/claude-agent.d.ts +20 -8
- package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude-agent.js +610 -460
- package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
- package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts +2 -2
- package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts.map +1 -1
- package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts +2 -2
- package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts.map +1 -1
- package/dist/server/server/agent/providers/codex/tool-call-mapper.js +49 -44
- package/dist/server/server/agent/providers/codex/tool-call-mapper.js.map +1 -1
- package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +27 -8
- package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/codex-app-server-agent.js +564 -492
- package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
- package/dist/server/server/agent/providers/codex-rollout-timeline.d.ts +2 -2
- package/dist/server/server/agent/providers/codex-rollout-timeline.d.ts.map +1 -1
- package/dist/server/server/agent/providers/codex-rollout-timeline.js +58 -47
- package/dist/server/server/agent/providers/codex-rollout-timeline.js.map +1 -1
- package/dist/server/server/agent/providers/copilot-acp-agent.d.ts +2 -2
- package/dist/server/server/agent/providers/copilot-acp-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/diagnostic-utils.d.ts +3 -3
- package/dist/server/server/agent/providers/diagnostic-utils.d.ts.map +1 -1
- package/dist/server/server/agent/providers/diagnostic-utils.js +82 -9
- package/dist/server/server/agent/providers/diagnostic-utils.js.map +1 -1
- package/dist/server/server/agent/providers/generic-acp-agent.d.ts +2 -2
- package/dist/server/server/agent/providers/generic-acp-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/mock-load-test-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/mock-load-test-agent.js.map +1 -1
- package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts +2 -2
- package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts.map +1 -1
- package/dist/server/server/agent/providers/opencode-agent.d.ts +2 -2
- package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/opencode-agent.js +385 -360
- package/dist/server/server/agent/providers/opencode-agent.js.map +1 -1
- package/dist/server/server/agent/providers/pi-direct-agent.d.ts +1 -0
- package/dist/server/server/agent/providers/pi-direct-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/pi-direct-agent.js +109 -140
- package/dist/server/server/agent/providers/pi-direct-agent.js.map +1 -1
- package/dist/server/server/agent/providers/test-utils/session-stream-adapter.d.ts.map +1 -1
- package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js +3 -1
- package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js.map +1 -1
- package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +3 -3
- package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -1
- package/dist/server/server/agent/providers/tool-call-detail-primitives.js +102 -73
- package/dist/server/server/agent/providers/tool-call-detail-primitives.js.map +1 -1
- package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts +2 -2
- package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts.map +1 -1
- package/dist/server/server/agent/stt-manager.d.ts.map +1 -1
- package/dist/server/server/agent/stt-manager.js +63 -53
- package/dist/server/server/agent/stt-manager.js.map +1 -1
- package/dist/server/server/agent/timeline-projection.d.ts +6 -6
- package/dist/server/server/agent/timeline-projection.d.ts.map +1 -1
- package/dist/server/server/agent/timeline-projection.js +11 -6
- package/dist/server/server/agent/timeline-projection.js.map +1 -1
- package/dist/server/server/agent/tts-manager.d.ts.map +1 -1
- package/dist/server/server/agent/tts-manager.js +1 -0
- package/dist/server/server/agent/tts-manager.js.map +1 -1
- package/dist/server/server/agent-attention-policy.d.ts +2 -2
- package/dist/server/server/agent-attention-policy.d.ts.map +1 -1
- package/dist/server/server/bootstrap.d.ts +4 -4
- package/dist/server/server/bootstrap.d.ts.map +1 -1
- package/dist/server/server/bootstrap.js +493 -485
- package/dist/server/server/bootstrap.js.map +1 -1
- package/dist/server/server/chat/chat-service.d.ts +1 -1
- package/dist/server/server/chat/chat-service.d.ts.map +1 -1
- package/dist/server/server/chat/chat-service.js +3 -3
- package/dist/server/server/chat/chat-service.js.map +1 -1
- package/dist/server/server/checkout-diff-manager.d.ts +2 -2
- package/dist/server/server/checkout-diff-manager.d.ts.map +1 -1
- package/dist/server/server/checkout-git-utils.d.ts +5 -3
- package/dist/server/server/checkout-git-utils.d.ts.map +1 -1
- package/dist/server/server/checkout-git-utils.js +1 -2
- package/dist/server/server/checkout-git-utils.js.map +1 -1
- package/dist/server/server/config.d.ts.map +1 -1
- package/dist/server/server/config.js +68 -39
- package/dist/server/server/config.js.map +1 -1
- package/dist/server/server/connection-offer.d.ts +2 -2
- package/dist/server/server/connection-offer.d.ts.map +1 -1
- package/dist/server/server/daemon-config-store.d.ts +5 -3
- package/dist/server/server/daemon-config-store.d.ts.map +1 -1
- package/dist/server/server/daemon-config-store.js +26 -0
- package/dist/server/server/daemon-config-store.js.map +1 -1
- package/dist/server/server/daemon-keypair.d.ts +2 -2
- package/dist/server/server/daemon-keypair.d.ts.map +1 -1
- package/dist/server/server/editor-targets.d.ts +4 -4
- package/dist/server/server/editor-targets.d.ts.map +1 -1
- package/dist/server/server/editor-targets.js +11 -15
- package/dist/server/server/editor-targets.js.map +1 -1
- package/dist/server/server/exports.d.ts +3 -3
- package/dist/server/server/exports.d.ts.map +1 -1
- package/dist/server/server/exports.js +1 -3
- package/dist/server/server/exports.js.map +1 -1
- package/dist/server/server/file-download/token-store.d.ts +4 -4
- package/dist/server/server/file-download/token-store.d.ts.map +1 -1
- package/dist/server/server/index.js +16 -12
- package/dist/server/server/index.js.map +1 -1
- package/dist/server/server/logger.d.ts +4 -4
- package/dist/server/server/logger.d.ts.map +1 -1
- package/dist/server/server/logger.js +26 -20
- package/dist/server/server/logger.js.map +1 -1
- package/dist/server/server/loop/rpc-schemas.d.ts +52 -52
- package/dist/server/server/loop-service.d.ts +13 -12
- package/dist/server/server/loop-service.d.ts.map +1 -1
- package/dist/server/server/loop-service.js +22 -18
- package/dist/server/server/loop-service.js.map +1 -1
- package/dist/server/server/package-version.d.ts +2 -2
- package/dist/server/server/package-version.d.ts.map +1 -1
- package/dist/server/server/package-version.js +19 -17
- package/dist/server/server/package-version.js.map +1 -1
- package/dist/server/server/pairing-offer.d.ts +2 -2
- package/dist/server/server/pairing-offer.d.ts.map +1 -1
- package/dist/server/server/paseo-env.d.ts +9 -0
- package/dist/server/server/paseo-env.d.ts.map +1 -0
- package/dist/server/server/paseo-env.js +70 -0
- package/dist/server/server/paseo-env.js.map +1 -0
- package/dist/server/server/paseo-worktree-archive-service.d.ts +4 -4
- package/dist/server/server/paseo-worktree-archive-service.d.ts.map +1 -1
- package/dist/server/server/paseo-worktree-archive-service.js +11 -11
- package/dist/server/server/paseo-worktree-archive-service.js.map +1 -1
- package/dist/server/server/persisted-config.d.ts +62 -62
- package/dist/server/server/persisted-config.d.ts.map +1 -1
- package/dist/server/server/persisted-config.js +4 -4
- package/dist/server/server/persisted-config.js.map +1 -1
- package/dist/server/server/persistence-hooks.d.ts +8 -9
- package/dist/server/server/persistence-hooks.d.ts.map +1 -1
- package/dist/server/server/persistence-hooks.js +4 -12
- package/dist/server/server/persistence-hooks.js.map +1 -1
- package/dist/server/server/pid-lock.js.map +1 -1
- package/dist/server/server/push/push-service.d.ts.map +1 -1
- package/dist/server/server/push/push-service.js +1 -3
- package/dist/server/server/push/push-service.js.map +1 -1
- package/dist/server/server/relay-transport.d.ts +8 -8
- package/dist/server/server/relay-transport.d.ts.map +1 -1
- package/dist/server/server/relay-transport.js +27 -16
- package/dist/server/server/relay-transport.js.map +1 -1
- package/dist/server/server/schedule/service.d.ts.map +1 -1
- package/dist/server/server/schedule/service.js +2 -2
- package/dist/server/server/schedule/service.js.map +1 -1
- package/dist/server/server/script-health-monitor.d.ts.map +1 -1
- package/dist/server/server/script-health-monitor.js +7 -6
- package/dist/server/server/script-health-monitor.js.map +1 -1
- package/dist/server/server/script-proxy.js +1 -1
- package/dist/server/server/script-proxy.js.map +1 -1
- package/dist/server/server/script-status-projection.d.ts +4 -4
- package/dist/server/server/script-status-projection.d.ts.map +1 -1
- package/dist/server/server/script-status-projection.js +54 -44
- package/dist/server/server/script-status-projection.js.map +1 -1
- package/dist/server/server/server-id.d.ts +4 -4
- package/dist/server/server/server-id.d.ts.map +1 -1
- package/dist/server/server/session.d.ts +50 -19
- package/dist/server/server/session.d.ts.map +1 -1
- package/dist/server/server/session.js +1116 -783
- package/dist/server/server/session.js.map +1 -1
- package/dist/server/server/speech/audio.js +1 -1
- package/dist/server/server/speech/audio.js.map +1 -1
- package/dist/server/server/speech/providers/local/config.d.ts +6 -6
- package/dist/server/server/speech/providers/local/config.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/config.js +41 -16
- package/dist/server/server/speech/providers/local/config.js.map +1 -1
- package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts +2 -2
- package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js +42 -19
- package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +1 -1
- package/dist/server/server/speech/providers/local/runtime.d.ts +4 -4
- package/dist/server/server/speech/providers/local/runtime.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/runtime.js +108 -77
- package/dist/server/server/speech/providers/local/runtime.js.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts +2 -2
- package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/model-catalog.js +1 -4
- package/dist/server/server/speech/providers/local/sherpa/model-catalog.js.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts +2 -2
- package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/model-downloader.js +19 -19
- package/dist/server/server/speech/providers/local/sherpa/model-downloader.js.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts +28 -7
- package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.d.ts +23 -4
- package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js +35 -28
- package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.d.ts +5 -5
- package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.d.ts +7 -7
- package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js +5 -0
- package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +3 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts +2 -2
- package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +3 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js +10 -4
- package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.d.ts +2 -2
- package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.d.ts +2 -2
- package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js +4 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts +2 -2
- package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts.map +1 -1
- package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js +18 -11
- package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js.map +1 -1
- package/dist/server/server/speech/providers/openai/config.d.ts +2 -2
- package/dist/server/server/speech/providers/openai/config.d.ts.map +1 -1
- package/dist/server/server/speech/providers/openai/config.js +58 -31
- package/dist/server/server/speech/providers/openai/config.js.map +1 -1
- package/dist/server/server/speech/providers/openai/realtime-transcription-session.d.ts.map +1 -1
- package/dist/server/server/speech/providers/openai/realtime-transcription-session.js +2 -2
- package/dist/server/server/speech/providers/openai/realtime-transcription-session.js.map +1 -1
- package/dist/server/server/speech/providers/openai/runtime.d.ts +4 -4
- package/dist/server/server/speech/providers/openai/runtime.d.ts.map +1 -1
- package/dist/server/server/speech/providers/openai/runtime.js +37 -32
- package/dist/server/server/speech/providers/openai/runtime.js.map +1 -1
- package/dist/server/server/speech/providers/openai/stt.d.ts.map +1 -1
- package/dist/server/server/speech/providers/openai/stt.js +4 -3
- package/dist/server/server/speech/providers/openai/stt.js.map +1 -1
- package/dist/server/server/speech/providers/openai/tts.d.ts.map +1 -1
- package/dist/server/server/speech/providers/openai/tts.js +3 -2
- package/dist/server/server/speech/providers/openai/tts.js.map +1 -1
- package/dist/server/server/speech/speech-config-resolver.d.ts.map +1 -1
- package/dist/server/server/speech/speech-config-resolver.js +46 -17
- package/dist/server/server/speech/speech-config-resolver.js.map +1 -1
- package/dist/server/server/speech/speech-provider.d.ts +2 -2
- package/dist/server/server/speech/speech-provider.d.ts.map +1 -1
- package/dist/server/server/speech/speech-runtime.d.ts +6 -6
- package/dist/server/server/speech/speech-runtime.d.ts.map +1 -1
- package/dist/server/server/speech/speech-runtime.js +17 -17
- package/dist/server/server/speech/speech-runtime.js.map +1 -1
- package/dist/server/server/speech/speech-types.d.ts +2 -2
- package/dist/server/server/speech/speech-types.d.ts.map +1 -1
- package/dist/server/server/speech/turn-detection-provider.d.ts +2 -2
- package/dist/server/server/speech/turn-detection-provider.d.ts.map +1 -1
- package/dist/server/server/utils/diff-highlighter.d.ts +0 -3
- package/dist/server/server/utils/diff-highlighter.d.ts.map +1 -1
- package/dist/server/server/utils/diff-highlighter.js +67 -66
- package/dist/server/server/utils/diff-highlighter.js.map +1 -1
- package/dist/server/server/voice/voice-turn-controller.d.ts.map +1 -1
- package/dist/server/server/voice/voice-turn-controller.js +1 -0
- package/dist/server/server/voice/voice-turn-controller.js.map +1 -1
- package/dist/server/server/voice-types.d.ts +2 -2
- package/dist/server/server/voice-types.d.ts.map +1 -1
- package/dist/server/server/websocket-server.d.ts +33 -23
- package/dist/server/server/websocket-server.d.ts.map +1 -1
- package/dist/server/server/websocket-server.js +349 -241
- package/dist/server/server/websocket-server.js.map +1 -1
- package/dist/server/server/workspace-git-metadata.d.ts +2 -2
- package/dist/server/server/workspace-git-metadata.d.ts.map +1 -1
- package/dist/server/server/workspace-git-metadata.js +2 -32
- package/dist/server/server/workspace-git-metadata.js.map +1 -1
- package/dist/server/server/workspace-git-service.d.ts +17 -13
- package/dist/server/server/workspace-git-service.d.ts.map +1 -1
- package/dist/server/server/workspace-git-service.js +232 -140
- package/dist/server/server/workspace-git-service.js.map +1 -1
- package/dist/server/server/workspace-reconciliation-service.d.ts +5 -4
- package/dist/server/server/workspace-reconciliation-service.d.ts.map +1 -1
- package/dist/server/server/workspace-reconciliation-service.js +82 -82
- package/dist/server/server/workspace-reconciliation-service.js.map +1 -1
- package/dist/server/server/workspace-registry-bootstrap.d.ts.map +1 -1
- package/dist/server/server/workspace-registry-bootstrap.js +40 -33
- package/dist/server/server/workspace-registry-bootstrap.js.map +1 -1
- package/dist/server/server/workspace-registry-model.d.ts +19 -6
- package/dist/server/server/workspace-registry-model.d.ts.map +1 -1
- package/dist/server/server/workspace-registry-model.js +35 -21
- package/dist/server/server/workspace-registry-model.js.map +1 -1
- package/dist/server/server/workspace-registry.d.ts +2 -2
- package/dist/server/server/workspace-script-runtime-store.d.ts +2 -2
- package/dist/server/server/workspace-script-runtime-store.d.ts.map +1 -1
- package/dist/server/server/workspace-service-env.js +3 -3
- package/dist/server/server/workspace-service-env.js.map +1 -1
- package/dist/server/server/worktree-bootstrap.d.ts +4 -4
- package/dist/server/server/worktree-bootstrap.d.ts.map +1 -1
- package/dist/server/server/worktree-bootstrap.js +95 -67
- package/dist/server/server/worktree-bootstrap.js.map +1 -1
- package/dist/server/server/worktree-session.d.ts +8 -8
- package/dist/server/server/worktree-session.d.ts.map +1 -1
- package/dist/server/server/worktree-session.js +27 -19
- package/dist/server/server/worktree-session.js.map +1 -1
- package/dist/server/services/github-service.d.ts +2 -7
- package/dist/server/services/github-service.d.ts.map +1 -1
- package/dist/server/services/github-service.js +156 -157
- package/dist/server/services/github-service.js.map +1 -1
- package/dist/server/shared/agent-attention-notification.d.ts +9 -8
- package/dist/server/shared/agent-attention-notification.d.ts.map +1 -1
- package/dist/server/shared/agent-attention-notification.js +27 -17
- package/dist/server/shared/agent-attention-notification.js.map +1 -1
- package/dist/server/shared/daemon-endpoints.d.ts +2 -2
- package/dist/server/shared/daemon-endpoints.d.ts.map +1 -1
- package/dist/server/shared/daemon-endpoints.js +17 -2
- package/dist/server/shared/daemon-endpoints.js.map +1 -1
- package/dist/server/shared/messages.d.ts +21962 -3049
- package/dist/server/shared/messages.d.ts.map +1 -1
- package/dist/server/shared/messages.js +79 -2
- package/dist/server/shared/messages.js.map +1 -1
- package/dist/server/shared/terminal-stream-protocol.d.ts +2 -2
- package/dist/server/shared/terminal-stream-protocol.d.ts.map +1 -1
- package/dist/server/shared/tool-call-display.d.ts +2 -2
- package/dist/server/shared/tool-call-display.d.ts.map +1 -1
- package/dist/server/terminal/terminal-manager.d.ts.map +1 -1
- package/dist/server/terminal/terminal-manager.js +1 -3
- package/dist/server/terminal/terminal-manager.js.map +1 -1
- package/dist/server/terminal/terminal-output-coalescer.d.ts +6 -6
- package/dist/server/terminal/terminal-output-coalescer.d.ts.map +1 -1
- package/dist/server/terminal/terminal.d.ts +3 -2
- package/dist/server/terminal/terminal.d.ts.map +1 -1
- package/dist/server/terminal/terminal.js +57 -19
- package/dist/server/terminal/terminal.js.map +1 -1
- package/dist/server/utils/checkout-git.d.ts +13 -12
- package/dist/server/utils/checkout-git.d.ts.map +1 -1
- package/dist/server/utils/checkout-git.js +416 -282
- package/dist/server/utils/checkout-git.js.map +1 -1
- package/dist/server/utils/directory-suggestions.js +12 -33
- package/dist/server/utils/directory-suggestions.js.map +1 -1
- package/dist/server/utils/executable.d.ts +1 -14
- package/dist/server/utils/executable.d.ts.map +1 -1
- package/dist/server/utils/executable.js +13 -49
- package/dist/server/utils/executable.js.map +1 -1
- package/dist/server/utils/github-remote.d.ts +13 -0
- package/dist/server/utils/github-remote.d.ts.map +1 -0
- package/dist/server/utils/github-remote.js +128 -0
- package/dist/server/utils/github-remote.js.map +1 -0
- package/dist/server/utils/paseo-config-file.d.ts +30 -0
- package/dist/server/utils/paseo-config-file.d.ts.map +1 -0
- package/dist/server/utils/paseo-config-file.js +90 -0
- package/dist/server/utils/paseo-config-file.js.map +1 -0
- package/dist/server/utils/paseo-config-schema.d.ts +290 -0
- package/dist/server/utils/paseo-config-schema.d.ts.map +1 -0
- package/dist/server/utils/paseo-config-schema.js +60 -0
- package/dist/server/utils/paseo-config-schema.js.map +1 -0
- package/dist/server/utils/project-icon.d.ts.map +1 -1
- package/dist/server/utils/project-icon.js +84 -109
- package/dist/server/utils/project-icon.js.map +1 -1
- package/dist/server/utils/promise-timeout.d.ts +2 -2
- package/dist/server/utils/promise-timeout.d.ts.map +1 -1
- package/dist/server/utils/run-git-command.d.ts +3 -1
- package/dist/server/utils/run-git-command.d.ts.map +1 -1
- package/dist/server/utils/run-git-command.js +10 -1
- package/dist/server/utils/run-git-command.js.map +1 -1
- package/dist/server/utils/script-hostname.d.ts +2 -2
- package/dist/server/utils/script-hostname.d.ts.map +1 -1
- package/dist/server/utils/spawn.d.ts +10 -3
- package/dist/server/utils/spawn.d.ts.map +1 -1
- package/dist/server/utils/spawn.js +30 -5
- package/dist/server/utils/spawn.js.map +1 -1
- package/dist/server/utils/windows-command.d.ts +15 -0
- package/dist/server/utils/windows-command.d.ts.map +1 -0
- package/dist/server/utils/windows-command.js +37 -0
- package/dist/server/utils/windows-command.js.map +1 -0
- package/dist/server/utils/worktree.d.ts +10 -7
- package/dist/server/utils/worktree.d.ts.map +1 -1
- package/dist/server/utils/worktree.js +64 -55
- package/dist/server/utils/worktree.js.map +1 -1
- package/dist/src/server/pid-lock.js.map +1 -1
- package/package.json +15 -20
- package/dist/server/server/agent/llm-openai.d.ts +0 -7
- package/dist/server/server/agent/llm-openai.d.ts.map +0 -1
- package/dist/server/server/agent/llm-openai.js +0 -8
- package/dist/server/server/agent/llm-openai.js.map +0 -1
- package/dist/server/server/agent/orchestrator.d.ts +0 -12
- package/dist/server/server/agent/orchestrator.d.ts.map +0 -1
- package/dist/server/server/agent/orchestrator.js +0 -12
- package/dist/server/server/agent/orchestrator.js.map +0 -1
- package/dist/server/server/types.d.ts +0 -5
- package/dist/server/server/types.d.ts.map +0 -1
- package/dist/server/server/types.js +0 -3
- package/dist/server/server/types.js.map +0 -1
- package/dist/server/server/workspace-registry.test-helpers.d.ts +0 -37
- package/dist/server/server/workspace-registry.test-helpers.d.ts.map +0 -1
- package/dist/server/server/workspace-registry.test-helpers.js +0 -121
- package/dist/server/server/workspace-registry.test-helpers.js.map +0 -1
|
@@ -3,13 +3,13 @@ import { existsSync, realpathSync } from "fs";
|
|
|
3
3
|
import { open as openFile, readFile, stat as statFile } from "fs/promises";
|
|
4
4
|
import { TTLCache } from "@isaacs/ttlcache";
|
|
5
5
|
import { parseAndHighlightDiff } from "../server/utils/diff-highlighter.js";
|
|
6
|
-
import {
|
|
6
|
+
import { parseGitHubRepoFromRemote } from "../server/workspace-git-metadata.js";
|
|
7
|
+
import { GitHubAuthenticationError, GitHubCliMissingError, GitHubCommandError, createGitHubService, resolveGitHubRepo, } from "../services/github-service.js";
|
|
7
8
|
import { parseGitRevParsePath, resolveGitRevParsePath } from "./git-rev-parse-path.js";
|
|
8
9
|
import { runGitCommand } from "./run-git-command.js";
|
|
9
10
|
import { isPaseoOwnedWorktreeCwd } from "./worktree.js";
|
|
10
|
-
import {
|
|
11
|
+
import { readPaseoWorktreeMetadata } from "./worktree-metadata.js";
|
|
11
12
|
const READ_ONLY_GIT_ENV = {
|
|
12
|
-
...process.env,
|
|
13
13
|
GIT_OPTIONAL_LOCKS: "0",
|
|
14
14
|
};
|
|
15
15
|
const DEFAULT_PULL_REQUEST_STATUS_CACHE_TTL_MS = 30000;
|
|
@@ -19,6 +19,7 @@ const SHORTSTAT_CACHE_MAX = 1000;
|
|
|
19
19
|
let pullRequestStatusCacheTtlMs = DEFAULT_PULL_REQUEST_STATUS_CACHE_TTL_MS;
|
|
20
20
|
let pullRequestStatusCache = createPullRequestStatusCache(pullRequestStatusCacheTtlMs);
|
|
21
21
|
const pullRequestStatusInFlight = new Map();
|
|
22
|
+
const lastSuccessfulPullRequestStatus = new Map();
|
|
22
23
|
let shortstatCacheTtlMs = DEFAULT_SHORTSTAT_CACHE_TTL_MS;
|
|
23
24
|
let shortstatCache = createShortstatCache(shortstatCacheTtlMs);
|
|
24
25
|
const shortstatInFlight = new Map();
|
|
@@ -39,6 +40,16 @@ function createShortstatCache(ttlMs) {
|
|
|
39
40
|
function getPullRequestStatusCacheKey(cwd) {
|
|
40
41
|
return resolve(cwd);
|
|
41
42
|
}
|
|
43
|
+
function rememberPullRequestStatus(cacheKey, status) {
|
|
44
|
+
lastSuccessfulPullRequestStatus.set(cacheKey, status);
|
|
45
|
+
if (lastSuccessfulPullRequestStatus.size <= PULL_REQUEST_STATUS_CACHE_MAX) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const oldest = lastSuccessfulPullRequestStatus.keys().next();
|
|
49
|
+
if (!oldest.done) {
|
|
50
|
+
lastSuccessfulPullRequestStatus.delete(oldest.value);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
42
53
|
function getShortstatCacheKey(cwd) {
|
|
43
54
|
return resolve(cwd);
|
|
44
55
|
}
|
|
@@ -48,6 +59,7 @@ export function __resetPullRequestStatusCacheForTests() {
|
|
|
48
59
|
pullRequestStatusCacheTtlMs = DEFAULT_PULL_REQUEST_STATUS_CACHE_TTL_MS;
|
|
49
60
|
pullRequestStatusCache = createPullRequestStatusCache(pullRequestStatusCacheTtlMs);
|
|
50
61
|
pullRequestStatusInFlight.clear();
|
|
62
|
+
lastSuccessfulPullRequestStatus.clear();
|
|
51
63
|
}
|
|
52
64
|
export function __setPullRequestStatusCacheTtlForTests(ttlMs) {
|
|
53
65
|
pullRequestStatusCache.clear();
|
|
@@ -55,6 +67,7 @@ export function __setPullRequestStatusCacheTtlForTests(ttlMs) {
|
|
|
55
67
|
pullRequestStatusCacheTtlMs = ttlMs;
|
|
56
68
|
pullRequestStatusCache = createPullRequestStatusCache(ttlMs);
|
|
57
69
|
pullRequestStatusInFlight.clear();
|
|
70
|
+
lastSuccessfulPullRequestStatus.clear();
|
|
58
71
|
}
|
|
59
72
|
export function __resetCheckoutShortstatCacheForTests() {
|
|
60
73
|
shortstatCache.clear();
|
|
@@ -99,7 +112,7 @@ async function listGitRefs(cwd, refPrefix) {
|
|
|
99
112
|
"--sort=-committerdate",
|
|
100
113
|
"--format=%(refname)%09%(committerdate:unix)",
|
|
101
114
|
refPrefix,
|
|
102
|
-
], { cwd,
|
|
115
|
+
], { cwd, envOverlay: READ_ONLY_GIT_ENV });
|
|
103
116
|
return stdout
|
|
104
117
|
.split("\n")
|
|
105
118
|
.map((line) => {
|
|
@@ -199,7 +212,7 @@ export async function resolveBranchCheckout(cwd, name) {
|
|
|
199
212
|
const localRef = `refs/heads/${normalized}`;
|
|
200
213
|
const localResult = await runGitCommand(["rev-parse", "--verify", "--quiet", localRef], {
|
|
201
214
|
cwd,
|
|
202
|
-
|
|
215
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
203
216
|
acceptExitCodes: [0, 1],
|
|
204
217
|
});
|
|
205
218
|
const hasLocal = localResult.exitCode === 0;
|
|
@@ -210,7 +223,7 @@ export async function resolveBranchCheckout(cwd, name) {
|
|
|
210
223
|
const remoteRefPath = `refs/remotes/${remoteRef}`;
|
|
211
224
|
const remoteResult = await runGitCommand(["rev-parse", "--verify", "--quiet", remoteRefPath], {
|
|
212
225
|
cwd,
|
|
213
|
-
|
|
226
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
214
227
|
acceptExitCodes: [0, 1],
|
|
215
228
|
});
|
|
216
229
|
const hasRemote = remoteResult.exitCode === 0;
|
|
@@ -245,7 +258,7 @@ async function listCheckoutFileChanges(cwd, refs, ignoreWhitespace = false) {
|
|
|
245
258
|
const { stdout: nameStatusOut } = await runGitCommand(buildGitDiffArgs({
|
|
246
259
|
ignoreWhitespace,
|
|
247
260
|
extra: ["--name-status", ...getCheckoutDiffRefArgs(refs)],
|
|
248
|
-
}), { cwd,
|
|
261
|
+
}), { cwd, envOverlay: READ_ONLY_GIT_ENV });
|
|
249
262
|
for (const line of nameStatusOut
|
|
250
263
|
.split("\n")
|
|
251
264
|
.map((l) => l.trim())
|
|
@@ -283,7 +296,7 @@ async function listCheckoutFileChanges(cwd, refs, ignoreWhitespace = false) {
|
|
|
283
296
|
if (refs.includeUntracked) {
|
|
284
297
|
const { stdout: untrackedOut } = await runGitCommand(["ls-files", "--others", "--exclude-standard"], {
|
|
285
298
|
cwd,
|
|
286
|
-
|
|
299
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
287
300
|
});
|
|
288
301
|
for (const file of untrackedOut
|
|
289
302
|
.split("\n")
|
|
@@ -316,7 +329,7 @@ async function readGitFileContentAtRef(cwd, ref, path) {
|
|
|
316
329
|
try {
|
|
317
330
|
const { stdout } = await runGitCommand(["show", `${ref}:${path}`], {
|
|
318
331
|
cwd,
|
|
319
|
-
|
|
332
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
320
333
|
});
|
|
321
334
|
return stdout;
|
|
322
335
|
}
|
|
@@ -328,7 +341,7 @@ async function tryResolveMergeBase(cwd, baseRef) {
|
|
|
328
341
|
try {
|
|
329
342
|
const { stdout } = await runGitCommand(["merge-base", baseRef, "HEAD"], {
|
|
330
343
|
cwd,
|
|
331
|
-
|
|
344
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
332
345
|
});
|
|
333
346
|
const sha = stdout.trim();
|
|
334
347
|
return sha.length > 0 ? sha : null;
|
|
@@ -360,7 +373,7 @@ async function getTrackedNumstatByPath(cwd, refs, ignoreWhitespace = false) {
|
|
|
360
373
|
extra: ["--numstat", ...getCheckoutDiffRefArgs(refs)],
|
|
361
374
|
}), {
|
|
362
375
|
cwd,
|
|
363
|
-
|
|
376
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
364
377
|
maxOutputBytes: TRACKED_DIFF_NUMSTAT_MAX_BYTES,
|
|
365
378
|
acceptExitCodes: [0],
|
|
366
379
|
});
|
|
@@ -435,9 +448,9 @@ function isGitError(error) {
|
|
|
435
448
|
}
|
|
436
449
|
async function requireGitRepo(cwd) {
|
|
437
450
|
try {
|
|
438
|
-
await runGitCommand(["rev-parse", "--git-dir"], { cwd,
|
|
451
|
+
await runGitCommand(["rev-parse", "--git-dir"], { cwd, envOverlay: READ_ONLY_GIT_ENV });
|
|
439
452
|
}
|
|
440
|
-
catch
|
|
453
|
+
catch {
|
|
441
454
|
throw new NotGitRepoError(cwd);
|
|
442
455
|
}
|
|
443
456
|
}
|
|
@@ -445,7 +458,7 @@ export async function getCurrentBranch(cwd) {
|
|
|
445
458
|
try {
|
|
446
459
|
const { stdout } = await runGitCommand(["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
447
460
|
cwd,
|
|
448
|
-
|
|
461
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
449
462
|
});
|
|
450
463
|
const branch = stdout.trim();
|
|
451
464
|
if (branch === "HEAD") {
|
|
@@ -458,11 +471,12 @@ export async function getCurrentBranch(cwd) {
|
|
|
458
471
|
}
|
|
459
472
|
}
|
|
460
473
|
async function getRebaseHeadBranch(cwd) {
|
|
461
|
-
|
|
474
|
+
const paths = ["rebase-merge/head-name", "rebase-apply/head-name"];
|
|
475
|
+
const results = await Promise.all(paths.map(async (path) => {
|
|
462
476
|
try {
|
|
463
477
|
const { stdout } = await runGitCommand(["rev-parse", "--git-path", path], {
|
|
464
478
|
cwd,
|
|
465
|
-
|
|
479
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
466
480
|
});
|
|
467
481
|
const headName = (await readFile(resolve(cwd, stdout.trim()), "utf8")).trim();
|
|
468
482
|
if (headName.startsWith("refs/heads/")) {
|
|
@@ -471,16 +485,16 @@ async function getRebaseHeadBranch(cwd) {
|
|
|
471
485
|
return headName || null;
|
|
472
486
|
}
|
|
473
487
|
catch {
|
|
474
|
-
|
|
488
|
+
return null;
|
|
475
489
|
}
|
|
476
|
-
}
|
|
477
|
-
return null;
|
|
490
|
+
}));
|
|
491
|
+
return results.find((result) => result !== null) ?? null;
|
|
478
492
|
}
|
|
479
493
|
async function getWorktreeRoot(cwd) {
|
|
480
494
|
try {
|
|
481
495
|
const { stdout } = await runGitCommand(["rev-parse", "--show-toplevel"], {
|
|
482
496
|
cwd,
|
|
483
|
-
|
|
497
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
484
498
|
});
|
|
485
499
|
return parseGitRevParsePath(stdout);
|
|
486
500
|
}
|
|
@@ -491,7 +505,7 @@ async function getWorktreeRoot(cwd) {
|
|
|
491
505
|
export async function getMainRepoRoot(cwd) {
|
|
492
506
|
const { stdout: commonDirOut } = await runGitCommand(["rev-parse", "--git-common-dir"], {
|
|
493
507
|
cwd,
|
|
494
|
-
|
|
508
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
495
509
|
});
|
|
496
510
|
const commonDir = resolveGitRevParsePath(cwd, commonDirOut);
|
|
497
511
|
if (!commonDir) {
|
|
@@ -503,7 +517,7 @@ export async function getMainRepoRoot(cwd) {
|
|
|
503
517
|
}
|
|
504
518
|
const { stdout: worktreeOut } = await runGitCommand(["worktree", "list", "--porcelain"], {
|
|
505
519
|
cwd,
|
|
506
|
-
|
|
520
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
507
521
|
});
|
|
508
522
|
const worktrees = parseWorktreeList(worktreeOut);
|
|
509
523
|
const nonBareNonPaseo = worktrees.filter((wt) => !wt.isBare && !isPaseoWorktreePath(wt.path));
|
|
@@ -561,7 +575,7 @@ async function getWorktreePathForBranch(cwd, branchName) {
|
|
|
561
575
|
try {
|
|
562
576
|
const { stdout } = await runGitCommand(["worktree", "list", "--porcelain"], {
|
|
563
577
|
cwd,
|
|
564
|
-
|
|
578
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
565
579
|
});
|
|
566
580
|
const entries = parseWorktreeList(stdout);
|
|
567
581
|
const ref = branchName.startsWith("refs/heads/") ? branchName : `refs/heads/${branchName}`;
|
|
@@ -584,25 +598,45 @@ export async function renameCurrentBranch(cwd, newName) {
|
|
|
584
598
|
const currentBranch = await getCurrentBranch(cwd);
|
|
585
599
|
return { previousBranch, currentBranch };
|
|
586
600
|
}
|
|
587
|
-
async function
|
|
601
|
+
async function getPaseoWorktreeForCwd(cwd, context) {
|
|
588
602
|
// Fast-path reject: non-worktree paths do not need expensive ownership checks.
|
|
589
603
|
if (!/[\\/]worktrees[\\/]/.test(cwd)) {
|
|
590
|
-
return {
|
|
604
|
+
return { isPaseoOwnedWorktree: false };
|
|
591
605
|
}
|
|
592
606
|
const ownership = await isPaseoOwnedWorktreeCwd(cwd, { paseoHome: context?.paseoHome });
|
|
593
607
|
if (!ownership.allowed) {
|
|
594
|
-
return {
|
|
608
|
+
return { isPaseoOwnedWorktree: false };
|
|
595
609
|
}
|
|
596
|
-
const worktreeRoot = (await getWorktreeRoot(cwd)) ?? cwd;
|
|
597
610
|
return {
|
|
598
|
-
baseRef: requirePaseoWorktreeBaseRefName(worktreeRoot),
|
|
599
611
|
isPaseoOwnedWorktree: true,
|
|
612
|
+
worktreeRoot: (await getWorktreeRoot(cwd)) ?? cwd,
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
function readPaseoWorktreeBaseRef(worktreeRoot) {
|
|
616
|
+
return readPaseoWorktreeMetadata(worktreeRoot)?.baseRefName ?? null;
|
|
617
|
+
}
|
|
618
|
+
async function getStoredBaseRefForCwd(cwd, context) {
|
|
619
|
+
const paseoWorktree = await getPaseoWorktreeForCwd(cwd, context);
|
|
620
|
+
if (!paseoWorktree.isPaseoOwnedWorktree) {
|
|
621
|
+
return null;
|
|
622
|
+
}
|
|
623
|
+
return readPaseoWorktreeBaseRef(paseoWorktree.worktreeRoot);
|
|
624
|
+
}
|
|
625
|
+
async function getResolvedBaseRefForCwd(cwd, context) {
|
|
626
|
+
const { resolvedBaseRef } = await resolveBaseRefForCwd(cwd, context);
|
|
627
|
+
return resolvedBaseRef;
|
|
628
|
+
}
|
|
629
|
+
async function resolveBaseRefForCwd(cwd, context) {
|
|
630
|
+
const storedBaseRef = await getStoredBaseRefForCwd(cwd, context);
|
|
631
|
+
return {
|
|
632
|
+
storedBaseRef,
|
|
633
|
+
resolvedBaseRef: storedBaseRef ?? (await resolveBaseRef(cwd)),
|
|
600
634
|
};
|
|
601
635
|
}
|
|
602
636
|
async function isWorkingTreeDirty(cwd) {
|
|
603
637
|
const { stdout } = await runGitCommand(["status", "--porcelain"], {
|
|
604
638
|
cwd,
|
|
605
|
-
|
|
639
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
606
640
|
});
|
|
607
641
|
return stdout.trim().length > 0;
|
|
608
642
|
}
|
|
@@ -610,7 +644,7 @@ export async function getOriginRemoteUrl(cwd) {
|
|
|
610
644
|
try {
|
|
611
645
|
const { stdout } = await runGitCommand(["config", "--get", "remote.origin.url"], {
|
|
612
646
|
cwd,
|
|
613
|
-
|
|
647
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
614
648
|
});
|
|
615
649
|
const url = stdout.trim();
|
|
616
650
|
return url.length > 0 ? url : null;
|
|
@@ -623,11 +657,50 @@ export async function hasOriginRemote(cwd) {
|
|
|
623
657
|
const url = await getOriginRemoteUrl(cwd);
|
|
624
658
|
return url !== null;
|
|
625
659
|
}
|
|
660
|
+
async function getGitConfigValue(cwd, key) {
|
|
661
|
+
try {
|
|
662
|
+
const { stdout } = await runGitCommand(["config", "--get", key], {
|
|
663
|
+
cwd,
|
|
664
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
665
|
+
});
|
|
666
|
+
const value = stdout.trim();
|
|
667
|
+
return value.length > 0 ? value : null;
|
|
668
|
+
}
|
|
669
|
+
catch {
|
|
670
|
+
return null;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
function parseBranchMergeHeadRef(mergeRef) {
|
|
674
|
+
const prefix = "refs/heads/";
|
|
675
|
+
if (!mergeRef?.startsWith(prefix)) {
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
const headRef = mergeRef.slice(prefix.length).trim();
|
|
679
|
+
return headRef.length > 0 ? headRef : null;
|
|
680
|
+
}
|
|
681
|
+
async function resolvePullRequestStatusLookupTarget(cwd, currentBranch) {
|
|
682
|
+
const remoteName = await getGitConfigValue(cwd, `branch.${currentBranch}.remote`);
|
|
683
|
+
if (!remoteName?.startsWith("paseo-pr-")) {
|
|
684
|
+
return { headRef: currentBranch };
|
|
685
|
+
}
|
|
686
|
+
const mergeRef = await getGitConfigValue(cwd, `branch.${currentBranch}.merge`);
|
|
687
|
+
const trackedHeadRef = parseBranchMergeHeadRef(mergeRef);
|
|
688
|
+
if (!trackedHeadRef) {
|
|
689
|
+
return { headRef: currentBranch };
|
|
690
|
+
}
|
|
691
|
+
const remoteUrl = await getGitConfigValue(cwd, `remote.${remoteName}.url`);
|
|
692
|
+
const remoteRepo = remoteUrl ? parseGitHubRepoFromRemote(remoteUrl) : null;
|
|
693
|
+
const headRepositoryOwner = remoteRepo?.split("/")[0];
|
|
694
|
+
return {
|
|
695
|
+
headRef: trackedHeadRef,
|
|
696
|
+
...(headRepositoryOwner ? { headRepositoryOwner } : {}),
|
|
697
|
+
};
|
|
698
|
+
}
|
|
626
699
|
export async function resolveAbsoluteGitDir(cwd) {
|
|
627
700
|
try {
|
|
628
701
|
const { stdout } = await runGitCommand(["rev-parse", "--absolute-git-dir"], {
|
|
629
702
|
cwd,
|
|
630
|
-
|
|
703
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
631
704
|
});
|
|
632
705
|
const gitDir = stdout.trim();
|
|
633
706
|
return gitDir.length > 0 ? gitDir : null;
|
|
@@ -665,7 +738,7 @@ export async function resolveRepositoryDefaultBranch(repoRoot) {
|
|
|
665
738
|
try {
|
|
666
739
|
const { stdout } = await runGitCommand(["symbolic-ref", "--quiet", "refs/remotes/origin/HEAD"], {
|
|
667
740
|
cwd: repoRoot,
|
|
668
|
-
|
|
741
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
669
742
|
});
|
|
670
743
|
const ref = stdout.trim();
|
|
671
744
|
if (ref) {
|
|
@@ -678,7 +751,7 @@ export async function resolveRepositoryDefaultBranch(repoRoot) {
|
|
|
678
751
|
try {
|
|
679
752
|
await runGitCommand(["show-ref", "--verify", "--quiet", `refs/heads/${localName}`], {
|
|
680
753
|
cwd: repoRoot,
|
|
681
|
-
|
|
754
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
682
755
|
});
|
|
683
756
|
return localName;
|
|
684
757
|
}
|
|
@@ -692,16 +765,16 @@ export async function resolveRepositoryDefaultBranch(repoRoot) {
|
|
|
692
765
|
}
|
|
693
766
|
const { stdout } = await runGitCommand(["branch", "--format=%(refname:short)"], {
|
|
694
767
|
cwd: repoRoot,
|
|
695
|
-
|
|
768
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
696
769
|
});
|
|
697
|
-
const branches = stdout
|
|
770
|
+
const branches = new Set(stdout
|
|
698
771
|
.split("\n")
|
|
699
772
|
.map((line) => line.trim())
|
|
700
|
-
.filter((line) => line.length > 0);
|
|
701
|
-
if (branches.
|
|
773
|
+
.filter((line) => line.length > 0));
|
|
774
|
+
if (branches.has("main")) {
|
|
702
775
|
return "main";
|
|
703
776
|
}
|
|
704
|
-
if (branches.
|
|
777
|
+
if (branches.has("master")) {
|
|
705
778
|
return "master";
|
|
706
779
|
}
|
|
707
780
|
return null;
|
|
@@ -728,7 +801,7 @@ function normalizeComparisonBaseRefName(input) {
|
|
|
728
801
|
async function doesGitRefExist(cwd, fullRef) {
|
|
729
802
|
const result = await runGitCommand(["show-ref", "--verify", "--quiet", fullRef], {
|
|
730
803
|
cwd,
|
|
731
|
-
|
|
804
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
732
805
|
acceptExitCodes: [0, 1],
|
|
733
806
|
});
|
|
734
807
|
return result.exitCode === 0;
|
|
@@ -764,7 +837,7 @@ async function resolveMostAheadBaseRef(cwd, normalizedBaseRef) {
|
|
|
764
837
|
if (!hasLocal && !hasOrigin) {
|
|
765
838
|
throw new Error(`Base branch not found locally or on origin: ${normalizedBaseRef}`);
|
|
766
839
|
}
|
|
767
|
-
const { stdout } = await runGitCommand(["rev-list", "--left-right", "--count", `${normalizedBaseRef}...origin/${normalizedBaseRef}`], { cwd,
|
|
840
|
+
const { stdout } = await runGitCommand(["rev-list", "--left-right", "--count", `${normalizedBaseRef}...origin/${normalizedBaseRef}`], { cwd, envOverlay: READ_ONLY_GIT_ENV });
|
|
768
841
|
const [localOnlyRaw, originOnlyRaw] = stdout.trim().split(/\s+/);
|
|
769
842
|
const localOnly = Number.parseInt(localOnlyRaw ?? "0", 10);
|
|
770
843
|
const originOnly = Number.parseInt(originOnlyRaw ?? "0", 10);
|
|
@@ -782,7 +855,7 @@ async function getAheadBehind(cwd, baseRef, currentBranch) {
|
|
|
782
855
|
return null;
|
|
783
856
|
}
|
|
784
857
|
const comparisonBaseRef = await resolveBestComparisonBaseRef(cwd, baseRef);
|
|
785
|
-
const { stdout } = await runGitCommand(["rev-list", "--left-right", "--count", `${comparisonBaseRef}...${currentBranch}`], { cwd,
|
|
858
|
+
const { stdout } = await runGitCommand(["rev-list", "--left-right", "--count", `${comparisonBaseRef}...${currentBranch}`], { cwd, envOverlay: READ_ONLY_GIT_ENV });
|
|
786
859
|
const [behindRaw, aheadRaw] = stdout.trim().split(/\s+/);
|
|
787
860
|
const behind = Number.parseInt(behindRaw ?? "0", 10);
|
|
788
861
|
const ahead = Number.parseInt(aheadRaw ?? "0", 10);
|
|
@@ -796,7 +869,7 @@ async function getAheadOfOrigin(cwd, currentBranch) {
|
|
|
796
869
|
return null;
|
|
797
870
|
}
|
|
798
871
|
try {
|
|
799
|
-
const { stdout } = await runGitCommand(["rev-list", "--count", `origin/${currentBranch}..${currentBranch}`], { cwd,
|
|
872
|
+
const { stdout } = await runGitCommand(["rev-list", "--count", `origin/${currentBranch}..${currentBranch}`], { cwd, envOverlay: READ_ONLY_GIT_ENV });
|
|
800
873
|
const count = Number.parseInt(stdout.trim(), 10);
|
|
801
874
|
return Number.isNaN(count) ? null : count;
|
|
802
875
|
}
|
|
@@ -804,7 +877,7 @@ async function getAheadOfOrigin(cwd, currentBranch) {
|
|
|
804
877
|
try {
|
|
805
878
|
const { stdout } = await runGitCommand(["rev-list", "--count", currentBranch], {
|
|
806
879
|
cwd,
|
|
807
|
-
|
|
880
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
808
881
|
});
|
|
809
882
|
const count = Number.parseInt(stdout.trim(), 10);
|
|
810
883
|
return Number.isNaN(count) ? null : count;
|
|
@@ -819,7 +892,7 @@ async function getBehindOfOrigin(cwd, currentBranch) {
|
|
|
819
892
|
return null;
|
|
820
893
|
}
|
|
821
894
|
try {
|
|
822
|
-
const { stdout } = await runGitCommand(["rev-list", "--count", `${currentBranch}..origin/${currentBranch}`], { cwd,
|
|
895
|
+
const { stdout } = await runGitCommand(["rev-list", "--count", `${currentBranch}..origin/${currentBranch}`], { cwd, envOverlay: READ_ONLY_GIT_ENV });
|
|
823
896
|
const count = Number.parseInt(stdout.trim(), 10);
|
|
824
897
|
return Number.isNaN(count) ? null : count;
|
|
825
898
|
}
|
|
@@ -833,16 +906,16 @@ async function inspectCheckoutContext(cwd, context) {
|
|
|
833
906
|
if (!root) {
|
|
834
907
|
return null;
|
|
835
908
|
}
|
|
836
|
-
const [currentBranch, remoteUrl,
|
|
909
|
+
const [currentBranch, remoteUrl, paseoWorktree] = await Promise.all([
|
|
837
910
|
getCurrentBranch(cwd),
|
|
838
911
|
getOriginRemoteUrl(cwd),
|
|
839
|
-
|
|
912
|
+
getPaseoWorktreeForCwd(cwd, context),
|
|
840
913
|
]);
|
|
841
914
|
return {
|
|
842
915
|
worktreeRoot: root,
|
|
843
916
|
currentBranch,
|
|
844
917
|
remoteUrl,
|
|
845
|
-
|
|
918
|
+
paseoWorktree,
|
|
846
919
|
};
|
|
847
920
|
}
|
|
848
921
|
catch (error) {
|
|
@@ -929,7 +1002,7 @@ async function getUntrackedDiffText(cwd, change, ignoreWhitespace = false) {
|
|
|
929
1002
|
extra: ["--no-index", "/dev/null", "--", change.path],
|
|
930
1003
|
}), {
|
|
931
1004
|
cwd,
|
|
932
|
-
|
|
1005
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
933
1006
|
maxOutputBytes: PER_FILE_DIFF_MAX_BYTES,
|
|
934
1007
|
acceptExitCodes: [0, 1],
|
|
935
1008
|
});
|
|
@@ -947,24 +1020,24 @@ export async function getCheckoutStatus(cwd, context) {
|
|
|
947
1020
|
const worktreeRoot = inspected.worktreeRoot;
|
|
948
1021
|
const currentBranch = inspected.currentBranch;
|
|
949
1022
|
const remoteUrl = inspected.remoteUrl;
|
|
950
|
-
const
|
|
1023
|
+
const paseoWorktree = inspected.paseoWorktree;
|
|
951
1024
|
const isDirty = await isWorkingTreeDirty(cwd);
|
|
952
1025
|
const hasRemote = remoteUrl !== null;
|
|
953
|
-
const
|
|
1026
|
+
const { resolvedBaseRef: baseRef } = await resolveBaseRefForCwd(cwd, context);
|
|
1027
|
+
const mainRepoRoot = await getMainRepoRoot(cwd).catch(() => null);
|
|
954
1028
|
const [aheadBehind, aheadOfOrigin, behindOfOrigin] = await Promise.all([
|
|
955
1029
|
baseRef && currentBranch ? getAheadBehind(cwd, baseRef, currentBranch) : Promise.resolve(null),
|
|
956
1030
|
hasRemote && currentBranch ? getAheadOfOrigin(cwd, currentBranch) : Promise.resolve(null),
|
|
957
1031
|
hasRemote && currentBranch ? getBehindOfOrigin(cwd, currentBranch) : Promise.resolve(null),
|
|
958
1032
|
]);
|
|
959
|
-
if (
|
|
960
|
-
const mainRepoRoot = await getMainRepoRoot(cwd);
|
|
1033
|
+
if (paseoWorktree.isPaseoOwnedWorktree && baseRef) {
|
|
961
1034
|
return {
|
|
962
1035
|
isGit: true,
|
|
963
1036
|
repoRoot: worktreeRoot,
|
|
964
|
-
mainRepoRoot,
|
|
1037
|
+
mainRepoRoot: mainRepoRoot ?? worktreeRoot,
|
|
965
1038
|
currentBranch,
|
|
966
1039
|
isDirty,
|
|
967
|
-
baseRef
|
|
1040
|
+
baseRef,
|
|
968
1041
|
aheadBehind,
|
|
969
1042
|
aheadOfOrigin,
|
|
970
1043
|
behindOfOrigin,
|
|
@@ -976,6 +1049,7 @@ export async function getCheckoutStatus(cwd, context) {
|
|
|
976
1049
|
return {
|
|
977
1050
|
isGit: true,
|
|
978
1051
|
repoRoot: worktreeRoot,
|
|
1052
|
+
mainRepoRoot: mainRepoRoot && resolve(mainRepoRoot) !== resolve(worktreeRoot) ? mainRepoRoot : null,
|
|
979
1053
|
currentBranch,
|
|
980
1054
|
isDirty,
|
|
981
1055
|
baseRef,
|
|
@@ -1014,8 +1088,7 @@ async function getCheckoutShortstatUncached(cwd, context) {
|
|
|
1014
1088
|
catch {
|
|
1015
1089
|
return null;
|
|
1016
1090
|
}
|
|
1017
|
-
const
|
|
1018
|
-
const localBaseRef = configured.baseRef ?? (await resolveBaseRef(cwd));
|
|
1091
|
+
const localBaseRef = await getResolvedBaseRefForCwd(cwd, context);
|
|
1019
1092
|
const currentBranch = await getCurrentBranch(cwd);
|
|
1020
1093
|
let comparisonRef;
|
|
1021
1094
|
if (currentBranch && localBaseRef && currentBranch !== localBaseRef) {
|
|
@@ -1039,7 +1112,7 @@ async function getCheckoutShortstatUncached(cwd, context) {
|
|
|
1039
1112
|
try {
|
|
1040
1113
|
const { stdout: mergeBaseOut } = await runGitCommand(["merge-base", "HEAD", comparisonRef], {
|
|
1041
1114
|
cwd,
|
|
1042
|
-
|
|
1115
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
1043
1116
|
});
|
|
1044
1117
|
const mergeBase = mergeBaseOut.trim();
|
|
1045
1118
|
if (!mergeBase) {
|
|
@@ -1047,7 +1120,7 @@ async function getCheckoutShortstatUncached(cwd, context) {
|
|
|
1047
1120
|
}
|
|
1048
1121
|
const { stdout } = await runGitCommand(["diff", "--shortstat", mergeBase], {
|
|
1049
1122
|
cwd,
|
|
1050
|
-
|
|
1123
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
1051
1124
|
});
|
|
1052
1125
|
return parseCheckoutShortstat(stdout);
|
|
1053
1126
|
}
|
|
@@ -1092,32 +1165,143 @@ export function warmCheckoutShortstatInBackground(cwd, context, onComplete) {
|
|
|
1092
1165
|
void getOrLoadCheckoutShortstat(cwd, context)
|
|
1093
1166
|
.then(() => {
|
|
1094
1167
|
onComplete?.();
|
|
1168
|
+
return;
|
|
1095
1169
|
})
|
|
1096
1170
|
.catch(() => {
|
|
1097
1171
|
// Non-critical: keep listing path resilient even if git commands fail.
|
|
1098
1172
|
});
|
|
1099
1173
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1174
|
+
async function appendStructuredTrackedDiffs(input) {
|
|
1175
|
+
const { cwd, trackedChanges, trackedChangeByPath, trackedNumstatByPath, trackedPlaceholderByPath, trackedDiffText, trackedDiffTruncated, refsForDiff, ignoreWhitespace, structured, appendTrackedPlaceholderComment, } = input;
|
|
1176
|
+
const parsedTrackedFiles = trackedDiffText.length > 0
|
|
1177
|
+
? await parseAndHighlightDiff(trackedDiffText, cwd, {
|
|
1178
|
+
getOldFileContent: async (file) => {
|
|
1179
|
+
const change = trackedChangeByPath.get(file.path);
|
|
1180
|
+
if (!change || change.isNew) {
|
|
1181
|
+
return null;
|
|
1182
|
+
}
|
|
1183
|
+
const refPath = change.oldPath ?? change.path;
|
|
1184
|
+
return readGitFileContentAtRef(cwd, refsForDiff.baseRef, refPath);
|
|
1185
|
+
},
|
|
1186
|
+
getNewFileContent: async (file) => {
|
|
1187
|
+
if (!refsForDiff.targetRef) {
|
|
1188
|
+
return null;
|
|
1189
|
+
}
|
|
1190
|
+
return readGitFileContentAtRef(cwd, refsForDiff.targetRef, file.path);
|
|
1191
|
+
},
|
|
1192
|
+
})
|
|
1193
|
+
: [];
|
|
1194
|
+
const parsedTrackedByPath = new Map(parsedTrackedFiles.map((file) => [file.path, file]));
|
|
1195
|
+
for (const change of trackedChanges) {
|
|
1196
|
+
const placeholder = trackedPlaceholderByPath.get(change.path);
|
|
1197
|
+
if (placeholder) {
|
|
1198
|
+
structured.push(buildPlaceholderParsedDiffFile(change, {
|
|
1199
|
+
status: placeholder.status,
|
|
1200
|
+
stat: placeholder.stat,
|
|
1201
|
+
}));
|
|
1202
|
+
appendTrackedPlaceholderComment(change, placeholder.status);
|
|
1203
|
+
continue;
|
|
1204
|
+
}
|
|
1205
|
+
const stat = trackedNumstatByPath.get(change.path) ?? null;
|
|
1206
|
+
const parsedFile = parsedTrackedByPath.get(change.path);
|
|
1207
|
+
if (parsedFile) {
|
|
1208
|
+
structured.push({
|
|
1209
|
+
...parsedFile,
|
|
1210
|
+
path: change.path,
|
|
1211
|
+
isNew: change.isNew,
|
|
1212
|
+
isDeleted: change.isDeleted,
|
|
1213
|
+
status: "ok",
|
|
1214
|
+
});
|
|
1215
|
+
continue;
|
|
1216
|
+
}
|
|
1217
|
+
// `git diff -w --name-status` can still report a modified path even when the
|
|
1218
|
+
// whitespace-filtered patch and numstat are both empty. Skip emitting a
|
|
1219
|
+
// structured placeholder in that case so whitespace-only edits truly disappear.
|
|
1220
|
+
if (ignoreWhitespace &&
|
|
1221
|
+
!trackedDiffTruncated &&
|
|
1222
|
+
change.status.startsWith("M") &&
|
|
1223
|
+
(!stat || (!stat.isBinary && stat.additions === 0 && stat.deletions === 0))) {
|
|
1224
|
+
continue;
|
|
1225
|
+
}
|
|
1226
|
+
structured.push({
|
|
1227
|
+
path: change.path,
|
|
1228
|
+
isNew: change.isNew,
|
|
1229
|
+
isDeleted: change.isDeleted,
|
|
1230
|
+
additions: stat?.additions ?? 0,
|
|
1231
|
+
deletions: stat?.deletions ?? 0,
|
|
1232
|
+
hunks: [],
|
|
1233
|
+
status: trackedDiffTruncated ? "too_large" : "ok",
|
|
1234
|
+
});
|
|
1105
1235
|
}
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1236
|
+
}
|
|
1237
|
+
async function processUntrackedChange(input) {
|
|
1238
|
+
const { cwd, change, ignoreWhitespace, includeStructured, structured, appendDiff } = input;
|
|
1239
|
+
const { text, truncated, stat } = await getUntrackedDiffText(cwd, change, ignoreWhitespace);
|
|
1240
|
+
if (!includeStructured) {
|
|
1241
|
+
if (stat?.isBinary) {
|
|
1242
|
+
appendDiff(`# ${change.path}: binary diff omitted\n`);
|
|
1243
|
+
}
|
|
1244
|
+
else if (truncated) {
|
|
1245
|
+
appendDiff(`# ${change.path}: diff too large omitted\n`);
|
|
1246
|
+
}
|
|
1247
|
+
else {
|
|
1248
|
+
appendDiff(text);
|
|
1249
|
+
}
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
if (stat?.isBinary) {
|
|
1253
|
+
structured.push(buildPlaceholderParsedDiffFile(change, { status: "binary", stat }));
|
|
1254
|
+
appendDiff(`# ${change.path}: binary diff omitted\n`);
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
if (truncated) {
|
|
1258
|
+
structured.push(buildPlaceholderParsedDiffFile(change, { status: "too_large", stat }));
|
|
1259
|
+
appendDiff(`# ${change.path}: diff too large omitted\n`);
|
|
1260
|
+
return;
|
|
1261
|
+
}
|
|
1262
|
+
appendDiff(text);
|
|
1263
|
+
const parsed = await parseAndHighlightDiff(text, cwd);
|
|
1264
|
+
const parsedFile = parsed[0] ??
|
|
1265
|
+
{
|
|
1266
|
+
path: change.path,
|
|
1267
|
+
isNew: change.isNew,
|
|
1268
|
+
isDeleted: change.isDeleted,
|
|
1269
|
+
additions: stat?.additions ?? 0,
|
|
1270
|
+
deletions: stat?.deletions ?? 0,
|
|
1271
|
+
hunks: [],
|
|
1120
1272
|
};
|
|
1273
|
+
structured.push({
|
|
1274
|
+
...parsedFile,
|
|
1275
|
+
path: change.path,
|
|
1276
|
+
isNew: change.isNew,
|
|
1277
|
+
isDeleted: change.isDeleted,
|
|
1278
|
+
status: "ok",
|
|
1279
|
+
});
|
|
1280
|
+
}
|
|
1281
|
+
async function resolveCheckoutDiffRefs(cwd, compare, context) {
|
|
1282
|
+
if (compare.mode === "uncommitted") {
|
|
1283
|
+
return { baseRef: "HEAD", includeUntracked: true };
|
|
1284
|
+
}
|
|
1285
|
+
const { storedBaseRef, resolvedBaseRef } = await resolveBaseRefForCwd(cwd, context);
|
|
1286
|
+
const baseRef = compare.baseRef ?? resolvedBaseRef;
|
|
1287
|
+
if (!baseRef) {
|
|
1288
|
+
return null;
|
|
1289
|
+
}
|
|
1290
|
+
if (storedBaseRef && compare.baseRef && compare.baseRef !== storedBaseRef) {
|
|
1291
|
+
throw new Error(`Base ref mismatch: expected ${baseRef}, got ${compare.baseRef}`);
|
|
1292
|
+
}
|
|
1293
|
+
const bestBaseRef = await resolveBestComparisonBaseRef(cwd, baseRef);
|
|
1294
|
+
return {
|
|
1295
|
+
baseRef: (await tryResolveMergeBase(cwd, bestBaseRef)) ?? bestBaseRef,
|
|
1296
|
+
targetRef: "HEAD",
|
|
1297
|
+
includeUntracked: false,
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
export async function getCheckoutDiff(cwd, compare, context) {
|
|
1301
|
+
await requireGitRepo(cwd);
|
|
1302
|
+
const refsForDiff = await resolveCheckoutDiffRefs(cwd, compare, context);
|
|
1303
|
+
if (!refsForDiff) {
|
|
1304
|
+
return { diff: "" };
|
|
1121
1305
|
}
|
|
1122
1306
|
const ignoreWhitespace = compare.ignoreWhitespace === true;
|
|
1123
1307
|
const changes = await listCheckoutFileChanges(cwd, refsForDiff, ignoreWhitespace);
|
|
@@ -1174,7 +1358,7 @@ export async function getCheckoutDiff(cwd, compare, context) {
|
|
|
1174
1358
|
extra: [...getCheckoutDiffRefArgs(refsForDiff), "--", ...trackedDiffPaths],
|
|
1175
1359
|
}), {
|
|
1176
1360
|
cwd,
|
|
1177
|
-
|
|
1361
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
1178
1362
|
maxOutputBytes: TOTAL_DIFF_MAX_BYTES,
|
|
1179
1363
|
});
|
|
1180
1364
|
trackedDiffText = trackedDiffResult.stdout;
|
|
@@ -1192,66 +1376,20 @@ export async function getCheckoutDiff(cwd, compare, context) {
|
|
|
1192
1376
|
appendDiff(`# ${change.path}: diff too large omitted\n`);
|
|
1193
1377
|
};
|
|
1194
1378
|
if (compare.includeStructured) {
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
return readGitFileContentAtRef(cwd, refsForDiff.targetRef, file.path);
|
|
1210
|
-
},
|
|
1211
|
-
})
|
|
1212
|
-
: [];
|
|
1213
|
-
const parsedTrackedByPath = new Map(parsedTrackedFiles.map((file) => [file.path, file]));
|
|
1214
|
-
for (const change of trackedChanges) {
|
|
1215
|
-
const placeholder = trackedPlaceholderByPath.get(change.path);
|
|
1216
|
-
if (placeholder) {
|
|
1217
|
-
structured.push(buildPlaceholderParsedDiffFile(change, {
|
|
1218
|
-
status: placeholder.status,
|
|
1219
|
-
stat: placeholder.stat,
|
|
1220
|
-
}));
|
|
1221
|
-
appendTrackedPlaceholderComment(change, placeholder.status);
|
|
1222
|
-
continue;
|
|
1223
|
-
}
|
|
1224
|
-
const stat = trackedNumstatByPath.get(change.path) ?? null;
|
|
1225
|
-
const parsedFile = parsedTrackedByPath.get(change.path);
|
|
1226
|
-
if (parsedFile) {
|
|
1227
|
-
structured.push({
|
|
1228
|
-
...parsedFile,
|
|
1229
|
-
path: change.path,
|
|
1230
|
-
isNew: change.isNew,
|
|
1231
|
-
isDeleted: change.isDeleted,
|
|
1232
|
-
status: "ok",
|
|
1233
|
-
});
|
|
1234
|
-
continue;
|
|
1235
|
-
}
|
|
1236
|
-
// `git diff -w --name-status` can still report a modified path even when the
|
|
1237
|
-
// whitespace-filtered patch and numstat are both empty. Skip emitting a
|
|
1238
|
-
// structured placeholder in that case so whitespace-only edits truly disappear.
|
|
1239
|
-
if (ignoreWhitespace &&
|
|
1240
|
-
!trackedDiffTruncated &&
|
|
1241
|
-
change.status.startsWith("M") &&
|
|
1242
|
-
(!stat || (!stat.isBinary && stat.additions === 0 && stat.deletions === 0))) {
|
|
1243
|
-
continue;
|
|
1244
|
-
}
|
|
1245
|
-
structured.push({
|
|
1246
|
-
path: change.path,
|
|
1247
|
-
isNew: change.isNew,
|
|
1248
|
-
isDeleted: change.isDeleted,
|
|
1249
|
-
additions: stat?.additions ?? 0,
|
|
1250
|
-
deletions: stat?.deletions ?? 0,
|
|
1251
|
-
hunks: [],
|
|
1252
|
-
status: trackedDiffTruncated ? "too_large" : "ok",
|
|
1253
|
-
});
|
|
1254
|
-
}
|
|
1379
|
+
await appendStructuredTrackedDiffs({
|
|
1380
|
+
cwd,
|
|
1381
|
+
trackedChanges,
|
|
1382
|
+
trackedChangeByPath,
|
|
1383
|
+
trackedNumstatByPath,
|
|
1384
|
+
trackedPlaceholderByPath,
|
|
1385
|
+
trackedDiffText,
|
|
1386
|
+
trackedDiffTruncated,
|
|
1387
|
+
refsForDiff,
|
|
1388
|
+
ignoreWhitespace,
|
|
1389
|
+
structured,
|
|
1390
|
+
appendDiff,
|
|
1391
|
+
appendTrackedPlaceholderComment,
|
|
1392
|
+
});
|
|
1255
1393
|
}
|
|
1256
1394
|
else {
|
|
1257
1395
|
for (const change of trackedChanges) {
|
|
@@ -1265,46 +1403,13 @@ export async function getCheckoutDiff(cwd, compare, context) {
|
|
|
1265
1403
|
if (diffBytes >= TOTAL_DIFF_MAX_BYTES) {
|
|
1266
1404
|
break;
|
|
1267
1405
|
}
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
}
|
|
1276
|
-
else {
|
|
1277
|
-
appendDiff(text);
|
|
1278
|
-
}
|
|
1279
|
-
continue;
|
|
1280
|
-
}
|
|
1281
|
-
if (stat?.isBinary) {
|
|
1282
|
-
structured.push(buildPlaceholderParsedDiffFile(change, { status: "binary", stat }));
|
|
1283
|
-
appendDiff(`# ${change.path}: binary diff omitted\n`);
|
|
1284
|
-
continue;
|
|
1285
|
-
}
|
|
1286
|
-
if (truncated) {
|
|
1287
|
-
structured.push(buildPlaceholderParsedDiffFile(change, { status: "too_large", stat }));
|
|
1288
|
-
appendDiff(`# ${change.path}: diff too large omitted\n`);
|
|
1289
|
-
continue;
|
|
1290
|
-
}
|
|
1291
|
-
appendDiff(text);
|
|
1292
|
-
const parsed = await parseAndHighlightDiff(text, cwd);
|
|
1293
|
-
const parsedFile = parsed[0] ??
|
|
1294
|
-
{
|
|
1295
|
-
path: change.path,
|
|
1296
|
-
isNew: change.isNew,
|
|
1297
|
-
isDeleted: change.isDeleted,
|
|
1298
|
-
additions: stat?.additions ?? 0,
|
|
1299
|
-
deletions: stat?.deletions ?? 0,
|
|
1300
|
-
hunks: [],
|
|
1301
|
-
};
|
|
1302
|
-
structured.push({
|
|
1303
|
-
...parsedFile,
|
|
1304
|
-
path: change.path,
|
|
1305
|
-
isNew: change.isNew,
|
|
1306
|
-
isDeleted: change.isDeleted,
|
|
1307
|
-
status: "ok",
|
|
1406
|
+
await processUntrackedChange({
|
|
1407
|
+
cwd,
|
|
1408
|
+
change,
|
|
1409
|
+
ignoreWhitespace,
|
|
1410
|
+
includeStructured: compare.includeStructured === true,
|
|
1411
|
+
structured,
|
|
1412
|
+
appendDiff,
|
|
1308
1413
|
});
|
|
1309
1414
|
}
|
|
1310
1415
|
if (compare.includeStructured) {
|
|
@@ -1325,15 +1430,66 @@ export async function commitChanges(cwd, options) {
|
|
|
1325
1430
|
export async function commitAll(cwd, message) {
|
|
1326
1431
|
await commitChanges(cwd, { message, addAll: true });
|
|
1327
1432
|
}
|
|
1433
|
+
async function detectAndThrowMergeToBaseConflict(input) {
|
|
1434
|
+
const { operationCwd, error, baseRef, currentBranch } = input;
|
|
1435
|
+
const errorDetails = error instanceof Error
|
|
1436
|
+
? `${error.message}\n${error.stderr ?? ""}\n${error.stdout ?? ""}`
|
|
1437
|
+
: String(error);
|
|
1438
|
+
try {
|
|
1439
|
+
const [unmergedOutput, lsFilesOutput, statusOutput] = await Promise.all([
|
|
1440
|
+
runGitCommand(["diff", "--name-only", "--diff-filter=U"], { cwd: operationCwd }),
|
|
1441
|
+
runGitCommand(["ls-files", "-u"], { cwd: operationCwd }),
|
|
1442
|
+
runGitCommand(["status", "--porcelain"], { cwd: operationCwd }),
|
|
1443
|
+
]);
|
|
1444
|
+
const statusConflicts = statusOutput.stdout
|
|
1445
|
+
.split("\n")
|
|
1446
|
+
.map((line) => line.trim())
|
|
1447
|
+
.filter(Boolean)
|
|
1448
|
+
.filter((line) => /^(UU|AA|DD|AU|UA|UD|DU)\s/.test(line))
|
|
1449
|
+
.map((line) => line.slice(3).trim());
|
|
1450
|
+
const conflicts = [
|
|
1451
|
+
...unmergedOutput.stdout
|
|
1452
|
+
.split("\n")
|
|
1453
|
+
.map((line) => line.trim())
|
|
1454
|
+
.filter(Boolean),
|
|
1455
|
+
...lsFilesOutput.stdout
|
|
1456
|
+
.split("\n")
|
|
1457
|
+
.map((line) => line.trim())
|
|
1458
|
+
.filter(Boolean)
|
|
1459
|
+
.map((line) => line.split("\t").pop()),
|
|
1460
|
+
...statusConflicts,
|
|
1461
|
+
].filter(Boolean);
|
|
1462
|
+
const conflictDetected = conflicts.length > 0 || /CONFLICT|Automatic merge failed/i.test(errorDetails);
|
|
1463
|
+
if (conflictDetected) {
|
|
1464
|
+
try {
|
|
1465
|
+
await runGitCommand(["merge", "--abort"], { cwd: operationCwd, timeout: 120000 });
|
|
1466
|
+
}
|
|
1467
|
+
catch {
|
|
1468
|
+
// ignore
|
|
1469
|
+
}
|
|
1470
|
+
throw new MergeConflictError({
|
|
1471
|
+
baseRef,
|
|
1472
|
+
currentBranch,
|
|
1473
|
+
conflictFiles: conflicts.length > 0 ? conflicts : [],
|
|
1474
|
+
});
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
catch (innerError) {
|
|
1478
|
+
if (innerError instanceof MergeConflictError) {
|
|
1479
|
+
throw innerError;
|
|
1480
|
+
}
|
|
1481
|
+
// ignore detection failures
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1328
1484
|
export async function mergeToBase(cwd, options = {}, context) {
|
|
1329
1485
|
await requireGitRepo(cwd);
|
|
1330
1486
|
const currentBranch = await getCurrentBranch(cwd);
|
|
1331
|
-
const
|
|
1332
|
-
const baseRef =
|
|
1487
|
+
const { storedBaseRef, resolvedBaseRef } = await resolveBaseRefForCwd(cwd, context);
|
|
1488
|
+
const baseRef = options.baseRef ?? resolvedBaseRef;
|
|
1333
1489
|
if (!baseRef) {
|
|
1334
1490
|
throw new Error("Unable to determine base branch for merge");
|
|
1335
1491
|
}
|
|
1336
|
-
if (
|
|
1492
|
+
if (storedBaseRef && options.baseRef && options.baseRef !== storedBaseRef) {
|
|
1337
1493
|
throw new Error(`Base ref mismatch: expected ${baseRef}, got ${options.baseRef}`);
|
|
1338
1494
|
}
|
|
1339
1495
|
if (!currentBranch) {
|
|
@@ -1371,54 +1527,12 @@ export async function mergeToBase(cwd, options = {}, context) {
|
|
|
1371
1527
|
}
|
|
1372
1528
|
}
|
|
1373
1529
|
catch (error) {
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
runGitCommand(["ls-files", "-u"], { cwd: operationCwd }),
|
|
1381
|
-
runGitCommand(["status", "--porcelain"], { cwd: operationCwd }),
|
|
1382
|
-
]);
|
|
1383
|
-
const statusConflicts = statusOutput.stdout
|
|
1384
|
-
.split("\n")
|
|
1385
|
-
.map((line) => line.trim())
|
|
1386
|
-
.filter(Boolean)
|
|
1387
|
-
.filter((line) => /^(UU|AA|DD|AU|UA|UD|DU)\s/.test(line))
|
|
1388
|
-
.map((line) => line.slice(3).trim());
|
|
1389
|
-
const conflicts = [
|
|
1390
|
-
...unmergedOutput.stdout
|
|
1391
|
-
.split("\n")
|
|
1392
|
-
.map((line) => line.trim())
|
|
1393
|
-
.filter(Boolean),
|
|
1394
|
-
...lsFilesOutput.stdout
|
|
1395
|
-
.split("\n")
|
|
1396
|
-
.map((line) => line.trim())
|
|
1397
|
-
.filter(Boolean)
|
|
1398
|
-
.map((line) => line.split("\t").pop()),
|
|
1399
|
-
...statusConflicts,
|
|
1400
|
-
].filter(Boolean);
|
|
1401
|
-
const conflictDetected = conflicts.length > 0 || /CONFLICT|Automatic merge failed/i.test(errorDetails);
|
|
1402
|
-
if (conflictDetected) {
|
|
1403
|
-
try {
|
|
1404
|
-
await runGitCommand(["merge", "--abort"], { cwd: operationCwd, timeout: 120000 });
|
|
1405
|
-
}
|
|
1406
|
-
catch {
|
|
1407
|
-
// ignore
|
|
1408
|
-
}
|
|
1409
|
-
throw new MergeConflictError({
|
|
1410
|
-
baseRef: normalizedBaseRef,
|
|
1411
|
-
currentBranch,
|
|
1412
|
-
conflictFiles: conflicts.length > 0 ? conflicts : [],
|
|
1413
|
-
});
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
catch (innerError) {
|
|
1417
|
-
if (innerError instanceof MergeConflictError) {
|
|
1418
|
-
throw innerError;
|
|
1419
|
-
}
|
|
1420
|
-
// ignore detection failures
|
|
1421
|
-
}
|
|
1530
|
+
await detectAndThrowMergeToBaseConflict({
|
|
1531
|
+
operationCwd,
|
|
1532
|
+
error,
|
|
1533
|
+
baseRef: normalizedBaseRef,
|
|
1534
|
+
currentBranch,
|
|
1535
|
+
});
|
|
1422
1536
|
throw error;
|
|
1423
1537
|
}
|
|
1424
1538
|
finally {
|
|
@@ -1442,19 +1556,19 @@ export async function mergeFromBase(cwd, options = {}, context) {
|
|
|
1442
1556
|
if (!currentBranch || currentBranch === "HEAD") {
|
|
1443
1557
|
throw new Error("Unable to determine current branch for merge");
|
|
1444
1558
|
}
|
|
1445
|
-
const
|
|
1446
|
-
const baseRef =
|
|
1559
|
+
const { storedBaseRef, resolvedBaseRef } = await resolveBaseRefForCwd(cwd, context);
|
|
1560
|
+
const baseRef = options.baseRef ?? resolvedBaseRef;
|
|
1447
1561
|
if (!baseRef) {
|
|
1448
1562
|
throw new Error("Unable to determine base branch for merge");
|
|
1449
1563
|
}
|
|
1450
|
-
if (
|
|
1564
|
+
if (storedBaseRef && options.baseRef && options.baseRef !== storedBaseRef) {
|
|
1451
1565
|
throw new Error(`Base ref mismatch: expected ${baseRef}, got ${options.baseRef}`);
|
|
1452
1566
|
}
|
|
1453
1567
|
const requireCleanTarget = options.requireCleanTarget ?? true;
|
|
1454
1568
|
if (requireCleanTarget) {
|
|
1455
1569
|
const { stdout } = await runGitCommand(["status", "--porcelain"], {
|
|
1456
1570
|
cwd,
|
|
1457
|
-
|
|
1571
|
+
envOverlay: READ_ONLY_GIT_ENV,
|
|
1458
1572
|
});
|
|
1459
1573
|
if (stdout.trim().length > 0) {
|
|
1460
1574
|
throw new Error("Working directory has uncommitted changes.");
|
|
@@ -1469,55 +1583,64 @@ export async function mergeFromBase(cwd, options = {}, context) {
|
|
|
1469
1583
|
await runGitCommand(["merge", bestBaseRef], { cwd, timeout: 120000 });
|
|
1470
1584
|
}
|
|
1471
1585
|
catch (error) {
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1586
|
+
await detectAndThrowMergeFromBaseConflict({
|
|
1587
|
+
cwd,
|
|
1588
|
+
error,
|
|
1589
|
+
baseRef: bestBaseRef,
|
|
1590
|
+
currentBranch,
|
|
1591
|
+
});
|
|
1592
|
+
throw error;
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
async function detectAndThrowMergeFromBaseConflict(input) {
|
|
1596
|
+
const { cwd, error, baseRef, currentBranch } = input;
|
|
1597
|
+
const errorDetails = error instanceof Error
|
|
1598
|
+
? `${error.message}\n${error.stderr ?? ""}\n${error.stdout ?? ""}`
|
|
1599
|
+
: String(error);
|
|
1600
|
+
try {
|
|
1601
|
+
const [unmergedOutput, lsFilesOutput, statusOutput] = await Promise.all([
|
|
1602
|
+
runGitCommand(["diff", "--name-only", "--diff-filter=U"], { cwd }),
|
|
1603
|
+
runGitCommand(["ls-files", "-u"], { cwd }),
|
|
1604
|
+
runGitCommand(["status", "--porcelain"], { cwd }),
|
|
1605
|
+
]);
|
|
1606
|
+
const statusConflicts = statusOutput.stdout
|
|
1607
|
+
.split("\n")
|
|
1608
|
+
.map((line) => line.trim())
|
|
1609
|
+
.filter(Boolean)
|
|
1610
|
+
.filter((line) => /^(UU|AA|DD|AU|UA|UD|DU)\s/.test(line))
|
|
1611
|
+
.map((line) => line.slice(3).trim());
|
|
1612
|
+
const conflicts = [
|
|
1613
|
+
...unmergedOutput.stdout
|
|
1614
|
+
.split("\n")
|
|
1615
|
+
.map((line) => line.trim())
|
|
1616
|
+
.filter(Boolean),
|
|
1617
|
+
...lsFilesOutput.stdout
|
|
1482
1618
|
.split("\n")
|
|
1483
1619
|
.map((line) => line.trim())
|
|
1484
1620
|
.filter(Boolean)
|
|
1485
|
-
.
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
...lsFilesOutput.stdout
|
|
1493
|
-
.split("\n")
|
|
1494
|
-
.map((line) => line.trim())
|
|
1495
|
-
.filter(Boolean)
|
|
1496
|
-
.map((line) => line.split("\t").pop()),
|
|
1497
|
-
...statusConflicts,
|
|
1498
|
-
].filter(Boolean);
|
|
1499
|
-
const conflictDetected = conflicts.length > 0 || /CONFLICT|Automatic merge failed/i.test(errorDetails);
|
|
1500
|
-
if (conflictDetected) {
|
|
1501
|
-
try {
|
|
1502
|
-
await runGitCommand(["merge", "--abort"], { cwd, timeout: 120000 });
|
|
1503
|
-
}
|
|
1504
|
-
catch {
|
|
1505
|
-
// ignore
|
|
1506
|
-
}
|
|
1507
|
-
throw new MergeFromBaseConflictError({
|
|
1508
|
-
baseRef: bestBaseRef,
|
|
1509
|
-
currentBranch,
|
|
1510
|
-
conflictFiles: conflicts.length > 0 ? conflicts : [],
|
|
1511
|
-
});
|
|
1621
|
+
.map((line) => line.split("\t").pop()),
|
|
1622
|
+
...statusConflicts,
|
|
1623
|
+
].filter(Boolean);
|
|
1624
|
+
const conflictDetected = conflicts.length > 0 || /CONFLICT|Automatic merge failed/i.test(errorDetails);
|
|
1625
|
+
if (conflictDetected) {
|
|
1626
|
+
try {
|
|
1627
|
+
await runGitCommand(["merge", "--abort"], { cwd, timeout: 120000 });
|
|
1512
1628
|
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
if (innerError instanceof MergeFromBaseConflictError) {
|
|
1516
|
-
throw innerError;
|
|
1629
|
+
catch {
|
|
1630
|
+
// ignore
|
|
1517
1631
|
}
|
|
1518
|
-
|
|
1632
|
+
throw new MergeFromBaseConflictError({
|
|
1633
|
+
baseRef,
|
|
1634
|
+
currentBranch,
|
|
1635
|
+
conflictFiles: conflicts.length > 0 ? conflicts : [],
|
|
1636
|
+
});
|
|
1519
1637
|
}
|
|
1520
|
-
|
|
1638
|
+
}
|
|
1639
|
+
catch (innerError) {
|
|
1640
|
+
if (innerError instanceof MergeFromBaseConflictError) {
|
|
1641
|
+
throw innerError;
|
|
1642
|
+
}
|
|
1643
|
+
// ignore detection failures
|
|
1521
1644
|
}
|
|
1522
1645
|
}
|
|
1523
1646
|
export async function pullCurrentBranch(cwd, github) {
|
|
@@ -1552,15 +1675,15 @@ export async function pushCurrentBranch(cwd, github) {
|
|
|
1552
1675
|
await runGitCommand(["push", "-u", "origin", currentBranch], { cwd, timeout: 120000 });
|
|
1553
1676
|
github?.invalidate({ cwd });
|
|
1554
1677
|
}
|
|
1555
|
-
export async function createPullRequest(cwd, options, github = createGitHubService(),
|
|
1678
|
+
export async function createPullRequest(cwd, options, github = createGitHubService(), context) {
|
|
1556
1679
|
await requireGitRepo(cwd);
|
|
1557
|
-
const repo = await resolveGitHubRepo(cwd
|
|
1680
|
+
const repo = await resolveGitHubRepo(cwd);
|
|
1558
1681
|
if (!repo) {
|
|
1559
1682
|
throw new Error("Unable to determine GitHub repo from git remote");
|
|
1560
1683
|
}
|
|
1561
1684
|
const head = options.head ?? (await getCurrentBranch(cwd));
|
|
1562
|
-
const
|
|
1563
|
-
const base =
|
|
1685
|
+
const { storedBaseRef, resolvedBaseRef } = await resolveBaseRefForCwd(cwd, context);
|
|
1686
|
+
const base = options.base ?? resolvedBaseRef;
|
|
1564
1687
|
if (!head) {
|
|
1565
1688
|
throw new Error("Unable to determine head branch for PR");
|
|
1566
1689
|
}
|
|
@@ -1568,7 +1691,7 @@ export async function createPullRequest(cwd, options, github = createGitHubServi
|
|
|
1568
1691
|
throw new Error("Unable to determine base branch for PR");
|
|
1569
1692
|
}
|
|
1570
1693
|
const normalizedBase = normalizeLocalBranchRefName(base);
|
|
1571
|
-
if (
|
|
1694
|
+
if (storedBaseRef && options.base && options.base !== storedBaseRef) {
|
|
1572
1695
|
throw new Error(`Base ref mismatch: expected ${base}, got ${options.base}`);
|
|
1573
1696
|
}
|
|
1574
1697
|
await runGitCommand(["push", "-u", "origin", head], { cwd, timeout: 120000 });
|
|
@@ -1598,7 +1721,17 @@ export async function getPullRequestStatus(cwd, github = createGitHubService(),
|
|
|
1598
1721
|
const lookup = getPullRequestStatusUncached(cwd, github, options)
|
|
1599
1722
|
.then((status) => {
|
|
1600
1723
|
pullRequestStatusCache.set(cacheKey, status);
|
|
1724
|
+
rememberPullRequestStatus(cacheKey, status);
|
|
1601
1725
|
return status;
|
|
1726
|
+
})
|
|
1727
|
+
.catch((error) => {
|
|
1728
|
+
if (error instanceof GitHubCommandError) {
|
|
1729
|
+
const stale = lastSuccessfulPullRequestStatus.get(cacheKey);
|
|
1730
|
+
if (stale) {
|
|
1731
|
+
return stale;
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
throw error;
|
|
1602
1735
|
})
|
|
1603
1736
|
.finally(() => {
|
|
1604
1737
|
pullRequestStatusInFlight.delete(cacheKey);
|
|
@@ -1616,9 +1749,10 @@ async function getPullRequestStatusUncached(cwd, github, options) {
|
|
|
1616
1749
|
};
|
|
1617
1750
|
}
|
|
1618
1751
|
try {
|
|
1752
|
+
const lookupTarget = await resolvePullRequestStatusLookupTarget(cwd, head);
|
|
1619
1753
|
const status = await github.getCurrentPullRequestStatus({
|
|
1620
1754
|
cwd,
|
|
1621
|
-
|
|
1755
|
+
...lookupTarget,
|
|
1622
1756
|
reason: options?.reason,
|
|
1623
1757
|
});
|
|
1624
1758
|
return {
|