@oh-my-pi/pi-coding-agent 15.10.9 → 15.10.11
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/CHANGELOG.md +117 -0
- package/dist/cli.js +23087 -0
- package/dist/tokenizers.linux-x64-gnu-xcjh3jwk.node +0 -0
- package/dist/types/async/job-manager.d.ts +18 -0
- package/dist/types/cli/args.d.ts +1 -1
- package/dist/types/cli/dry-balance-cli.d.ts +1 -1
- package/dist/types/cli/gallery-cli.d.ts +1 -1
- package/dist/types/cli/gallery-fixtures/types.d.ts +1 -1
- package/dist/types/cli/usage-cli.d.ts +72 -0
- package/dist/types/commands/launch.d.ts +1 -1
- package/dist/types/commands/read.d.ts +1 -1
- package/dist/types/commands/usage.d.ts +25 -0
- package/dist/types/config/append-only-context-mode.d.ts +2 -1
- package/dist/types/config/model-discovery.d.ts +55 -0
- package/dist/types/config/model-registry.d.ts +20 -219
- package/dist/types/config/model-resolver.d.ts +16 -10
- package/dist/types/config/model-roles.d.ts +28 -0
- package/dist/types/config/models-config-schema.d.ts +523 -42
- package/dist/types/config/models-config.d.ts +385 -0
- package/dist/types/config/settings-schema.d.ts +12 -16
- package/dist/types/config/settings.d.ts +1 -1
- package/dist/types/debug/log-viewer.d.ts +1 -1
- package/dist/types/debug/raw-sse.d.ts +1 -1
- package/dist/types/debug/terminal-info.d.ts +0 -1
- package/dist/types/eval/backend.d.ts +0 -2
- package/dist/types/eval/idle-timeout.d.ts +0 -4
- package/dist/types/eval/js/shared/rewrite-imports.d.ts +6 -6
- package/dist/types/export/html/template.generated.d.ts +1 -1
- package/dist/types/extensibility/extensions/types.d.ts +3 -3
- package/dist/types/hindsight/mental-models.d.ts +17 -8
- package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
- package/dist/types/internal-urls/types.d.ts +1 -1
- package/dist/types/lsp/edits.d.ts +9 -0
- package/dist/types/lsp/index.d.ts +2 -2
- package/dist/types/lsp/types.d.ts +2 -0
- package/dist/types/lsp/utils.d.ts +3 -0
- package/dist/types/mcp/json-rpc.d.ts +5 -0
- package/dist/types/mnemopi/state.d.ts +11 -1
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
- package/dist/types/modes/components/assistant-message.d.ts +3 -1
- package/dist/types/modes/components/bash-execution.d.ts +1 -1
- package/dist/types/modes/components/copy-selector.d.ts +1 -1
- package/dist/types/modes/components/dynamic-border.d.ts +1 -1
- package/dist/types/modes/components/extensions/extension-dashboard.d.ts +1 -1
- package/dist/types/modes/components/extensions/extension-list.d.ts +1 -1
- package/dist/types/modes/components/extensions/inspector-panel.d.ts +1 -1
- package/dist/types/modes/components/footer.d.ts +1 -1
- package/dist/types/modes/components/hook-editor.d.ts +5 -0
- package/dist/types/modes/components/hook-input.d.ts +4 -0
- package/dist/types/modes/components/hook-selector.d.ts +1 -1
- package/dist/types/modes/components/model-selector.d.ts +1 -1
- package/dist/types/modes/components/plan-review-overlay.d.ts +1 -1
- package/dist/types/modes/components/session-observer-overlay.d.ts +1 -1
- package/dist/types/modes/components/session-selector.d.ts +1 -1
- package/dist/types/modes/components/status-line/component.d.ts +1 -1
- package/dist/types/modes/components/tiny-title-download-progress.d.ts +1 -1
- package/dist/types/modes/components/transcript-container.d.ts +31 -26
- package/dist/types/modes/components/tree-selector.d.ts +1 -1
- package/dist/types/modes/components/user-message-selector.d.ts +1 -1
- package/dist/types/modes/components/user-message.d.ts +2 -1
- package/dist/types/modes/components/visual-truncate.d.ts +1 -1
- package/dist/types/modes/components/welcome.d.ts +19 -3
- package/dist/types/modes/controllers/mcp-command-controller.d.ts +1 -1
- package/dist/types/modes/controllers/streaming-reveal.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/modes/setup-wizard/scenes/sign-in.d.ts +1 -1
- package/dist/types/modes/setup-wizard/scenes/types.d.ts +1 -1
- package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +1 -1
- package/dist/types/modes/setup-wizard/wizard-overlay.d.ts +1 -1
- package/dist/types/modes/types.d.ts +2 -1
- package/dist/types/session/agent-session.d.ts +1 -1
- package/dist/types/session/auth-broker-config.d.ts +4 -0
- package/dist/types/session/session-manager.d.ts +1 -1
- package/dist/types/slash-commands/helpers/stats-dashboard.d.ts +13 -0
- package/dist/types/ssh/connection-manager.d.ts +8 -0
- package/dist/types/task/discovery.d.ts +1 -2
- package/dist/types/task/parallel.d.ts +2 -2
- package/dist/types/task/worktree.d.ts +2 -0
- package/dist/types/tiny/title-client.d.ts +1 -1
- package/dist/types/tools/ask.d.ts +4 -0
- package/dist/types/tools/conflict-detect.d.ts +16 -0
- package/dist/types/tools/github-cache.d.ts +7 -0
- package/dist/types/tools/sqlite-reader.d.ts +3 -0
- package/dist/types/tools/todo.d.ts +2 -0
- package/dist/types/tui/output-block.d.ts +3 -3
- package/dist/types/utils/changelog.d.ts +8 -0
- package/dist/types/web/scrapers/readthedocs.d.ts +3 -0
- package/dist/types/web/scrapers/types.d.ts +12 -0
- package/dist/types/web/search/providers/codex.d.ts +1 -1
- package/dist/types/web/search/providers/gemini.d.ts +1 -1
- package/examples/extensions/tools.ts +5 -4
- package/package.json +14 -11
- package/scripts/build-binary.ts +18 -23
- package/scripts/bundle-dist.ts +81 -0
- package/scripts/{dev-launch → omp} +1 -1
- package/scripts/{dev-launch-preload.ts → omp.ts} +1 -1
- package/src/async/job-manager.ts +57 -3
- package/src/autoresearch/dashboard.ts +1 -1
- package/src/autoresearch/prompt-setup.md +6 -6
- package/src/autoresearch/prompt.md +6 -6
- package/src/capability/fs.ts +10 -0
- package/src/cli/args.ts +1 -1
- package/src/cli/auth-gateway-cli.ts +1 -3
- package/src/cli/dry-balance-cli.ts +1 -1
- package/src/cli/gallery-cli.ts +1 -1
- package/src/cli/gallery-fixtures/fs.ts +1 -1
- package/src/cli/gallery-fixtures/types.ts +5 -1
- package/src/cli/list-models.ts +7 -12
- package/src/cli/usage-cli.ts +603 -0
- package/src/cli-commands.ts +1 -0
- package/src/cli.ts +69 -5
- package/src/commands/complete.ts +1 -1
- package/src/commands/launch.ts +1 -1
- package/src/commands/read.ts +6 -3
- package/src/commands/usage.ts +35 -0
- package/src/commit/agentic/agent.ts +1 -1
- package/src/commit/model-selection.ts +1 -1
- package/src/config/append-only-context-mode.ts +6 -12
- package/src/config/model-discovery.ts +554 -0
- package/src/config/model-registry.ts +308 -1025
- package/src/config/model-resolver.ts +113 -156
- package/src/config/model-roles.ts +74 -0
- package/src/config/models-config-schema.ts +57 -8
- package/src/config/models-config.ts +129 -0
- package/src/config/settings-schema.ts +18 -14
- package/src/config/settings.ts +37 -1
- package/src/dap/client.ts +124 -37
- package/src/dap/session.ts +259 -158
- package/src/debug/log-viewer.ts +1 -1
- package/src/debug/raw-sse.ts +1 -1
- package/src/debug/terminal-info.ts +0 -3
- package/src/edit/diff.ts +95 -18
- package/src/edit/hashline/block-resolver.ts +20 -1
- package/src/edit/hashline/diff.ts +36 -1
- package/src/edit/hashline/execute.ts +8 -2
- package/src/edit/index.ts +16 -1
- package/src/edit/modes/patch.ts +52 -0
- package/src/edit/modes/replace.ts +56 -22
- package/src/edit/notebook.ts +22 -2
- package/src/edit/renderer.ts +36 -10
- package/src/eval/__tests__/completion-bridge.test.ts +1 -1
- package/src/eval/backend.ts +0 -2
- package/src/eval/completion-bridge.ts +2 -1
- package/src/eval/idle-timeout.ts +2 -9
- package/src/eval/js/context-manager.ts +6 -8
- package/src/eval/js/executor.ts +6 -2
- package/src/eval/js/index.ts +0 -2
- package/src/eval/js/shared/helpers.ts +5 -6
- package/src/eval/js/shared/local-module-loader.ts +1 -1
- package/src/eval/js/shared/prelude.txt +62 -1
- package/src/eval/js/shared/rewrite-imports.ts +49 -23
- package/src/eval/js/shared/runtime.ts +1 -1
- package/src/eval/py/index.ts +0 -2
- package/src/eval/py/kernel.ts +19 -0
- package/src/eval/py/runner.py +107 -3
- package/src/exec/bash-executor.ts +3 -1
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +3 -1
- package/src/extensibility/extensions/types.ts +3 -2
- package/src/extensibility/plugins/legacy-pi-compat.ts +20 -3
- package/src/hindsight/mental-models.ts +59 -12
- package/src/hindsight/state.ts +6 -1
- package/src/internal-urls/artifact-protocol.ts +11 -2
- package/src/internal-urls/docs-index.generated.ts +10 -10
- package/src/internal-urls/issue-pr-protocol.ts +12 -5
- package/src/internal-urls/router.ts +1 -1
- package/src/internal-urls/types.ts +1 -1
- package/src/lib/xai-http.ts +1 -1
- package/src/lsp/client.ts +118 -38
- package/src/lsp/clients/biome-client.ts +101 -39
- package/src/lsp/edits.ts +143 -95
- package/src/lsp/index.ts +31 -22
- package/src/lsp/render.ts +1 -1
- package/src/lsp/types.ts +2 -0
- package/src/lsp/utils.ts +28 -10
- package/src/main.ts +165 -17
- package/src/mcp/json-rpc.ts +35 -5
- package/src/mcp/transports/stdio.ts +7 -1
- package/src/memories/index.ts +2 -1
- package/src/mnemopi/backend.ts +25 -3
- package/src/mnemopi/state.ts +38 -2
- package/src/modes/components/agent-dashboard.ts +10 -7
- package/src/modes/components/assistant-message.ts +19 -13
- package/src/modes/components/bash-execution.ts +1 -1
- package/src/modes/components/copy-selector.ts +1 -1
- package/src/modes/components/diff.ts +13 -2
- package/src/modes/components/dynamic-border.ts +12 -3
- package/src/modes/components/extensions/extension-dashboard.ts +8 -5
- package/src/modes/components/extensions/extension-list.ts +1 -1
- package/src/modes/components/extensions/inspector-panel.ts +1 -1
- package/src/modes/components/footer.ts +1 -1
- package/src/modes/components/history-search.ts +1 -1
- package/src/modes/components/hook-editor.ts +8 -0
- package/src/modes/components/hook-input.ts +8 -0
- package/src/modes/components/hook-selector.ts +2 -2
- package/src/modes/components/model-selector.ts +66 -54
- package/src/modes/components/plan-review-overlay.ts +1 -1
- package/src/modes/components/session-observer-overlay.ts +2 -2
- package/src/modes/components/session-selector.ts +1 -1
- package/src/modes/components/settings-selector.ts +5 -1
- package/src/modes/components/status-line/component.ts +1 -1
- package/src/modes/components/tiny-title-download-progress.ts +1 -1
- package/src/modes/components/transcript-container.ts +373 -141
- package/src/modes/components/tree-selector.ts +3 -3
- package/src/modes/components/user-message-selector.ts +1 -1
- package/src/modes/components/user-message.ts +17 -5
- package/src/modes/components/visual-truncate.ts +1 -1
- package/src/modes/components/welcome.ts +108 -26
- package/src/modes/controllers/command-controller.ts +10 -3
- package/src/modes/controllers/event-controller.ts +73 -49
- package/src/modes/controllers/input-controller.ts +5 -5
- package/src/modes/controllers/mcp-command-controller.ts +1 -1
- package/src/modes/controllers/selector-controller.ts +1 -5
- package/src/modes/controllers/streaming-reveal.ts +85 -18
- package/src/modes/interactive-mode.ts +5 -19
- package/src/modes/setup-wizard/scenes/glyph.ts +1 -1
- package/src/modes/setup-wizard/scenes/providers.ts +1 -1
- package/src/modes/setup-wizard/scenes/sign-in.ts +1 -1
- package/src/modes/setup-wizard/scenes/theme.ts +1 -1
- package/src/modes/setup-wizard/scenes/types.ts +1 -1
- package/src/modes/setup-wizard/scenes/web-search.ts +1 -1
- package/src/modes/setup-wizard/wizard-overlay.ts +1 -1
- package/src/modes/types.ts +2 -1
- package/src/prompts/agents/explore.md +2 -2
- package/src/prompts/agents/librarian.md +1 -2
- package/src/prompts/agents/oracle.md +1 -1
- package/src/prompts/agents/plan.md +5 -5
- package/src/prompts/agents/task.md +5 -5
- package/src/prompts/ci-green-request.md +5 -7
- package/src/prompts/goals/goal-budget-limit.md +2 -2
- package/src/prompts/goals/goal-continuation.md +4 -4
- package/src/prompts/goals/goal-mode-active.md +1 -1
- package/src/prompts/memories/read-path.md +1 -1
- package/src/prompts/memories/stage_one_system.md +2 -2
- package/src/prompts/review-custom-request.md +1 -1
- package/src/prompts/system/agent-creation-architect.md +2 -2
- package/src/prompts/system/auto-continue.md +1 -1
- package/src/prompts/system/background-tan-dispatch.md +1 -1
- package/src/prompts/system/btw-user.md +2 -2
- package/src/prompts/system/commit-message-system.md +13 -1
- package/src/prompts/system/custom-system-prompt.md +1 -1
- package/src/prompts/system/eager-todo.md +2 -2
- package/src/prompts/system/irc-incoming.md +1 -1
- package/src/prompts/system/manual-continue.md +1 -1
- package/src/prompts/system/omfg-user.md +3 -4
- package/src/prompts/system/orchestrate-notice.md +9 -9
- package/src/prompts/system/plan-mode-active.md +4 -4
- package/src/prompts/system/plan-mode-subagent.md +4 -5
- package/src/prompts/system/plan-mode-tool-decision-reminder.md +1 -1
- package/src/prompts/system/project-prompt.md +2 -2
- package/src/prompts/system/subagent-system-prompt.md +4 -4
- package/src/prompts/system/system-prompt.md +15 -26
- package/src/prompts/system/title-system.md +2 -2
- package/src/prompts/system/ttsr-tool-reminder.md +1 -1
- package/src/prompts/system/workflow-notice.md +1 -1
- package/src/prompts/tools/ast-edit.md +1 -1
- package/src/prompts/tools/ast-grep.md +2 -2
- package/src/prompts/tools/bash.md +8 -10
- package/src/prompts/tools/browser.md +7 -7
- package/src/prompts/tools/debug.md +1 -1
- package/src/prompts/tools/eval.md +3 -3
- package/src/prompts/tools/find.md +0 -1
- package/src/prompts/tools/github.md +8 -7
- package/src/prompts/tools/goal.md +1 -1
- package/src/prompts/tools/image-gen.md +1 -1
- package/src/prompts/tools/inspect-image-system.md +1 -1
- package/src/prompts/tools/irc.md +15 -15
- package/src/prompts/tools/lsp.md +2 -2
- package/src/prompts/tools/patch.md +2 -2
- package/src/prompts/tools/read.md +3 -4
- package/src/prompts/tools/recall.md +1 -1
- package/src/prompts/tools/reflect.md +1 -1
- package/src/prompts/tools/render-mermaid.md +2 -2
- package/src/prompts/tools/replace.md +4 -10
- package/src/prompts/tools/rewind.md +2 -2
- package/src/prompts/tools/search-tool-bm25.md +1 -9
- package/src/prompts/tools/search.md +0 -1
- package/src/prompts/tools/ssh.md +0 -4
- package/src/prompts/tools/task.md +2 -3
- package/src/prompts/tools/todo.md +6 -2
- package/src/sdk.ts +23 -10
- package/src/session/agent-session.ts +44 -10
- package/src/session/auth-broker-config.ts +30 -1
- package/src/session/session-manager.ts +2 -2
- package/src/session/streaming-output.ts +23 -2
- package/src/slash-commands/builtin-registry.ts +20 -0
- package/src/slash-commands/helpers/stats-dashboard.ts +85 -0
- package/src/ssh/connection-manager.ts +27 -0
- package/src/task/commands.ts +2 -1
- package/src/task/discovery.ts +17 -24
- package/src/task/executor.ts +61 -53
- package/src/task/index.ts +137 -60
- package/src/task/parallel.ts +3 -3
- package/src/task/render.ts +2 -2
- package/src/task/worktree.ts +64 -56
- package/src/thinking.ts +2 -1
- package/src/tiny/title-client.ts +32 -14
- package/src/tools/archive-reader.ts +30 -2
- package/src/tools/ask.ts +104 -21
- package/src/tools/ast-edit.ts +25 -5
- package/src/tools/auto-generated-guard.ts +20 -3
- package/src/tools/bash-interactive.ts +27 -7
- package/src/tools/bash.ts +54 -13
- package/src/tools/browser/launch.ts +11 -2
- package/src/tools/browser/readable.ts +19 -2
- package/src/tools/browser/registry.ts +4 -1
- package/src/tools/browser/render.ts +2 -2
- package/src/tools/browser/tab-supervisor.ts +55 -16
- package/src/tools/conflict-detect.ts +50 -4
- package/src/tools/debug.ts +1 -1
- package/src/tools/eval-render.ts +5 -5
- package/src/tools/eval.ts +0 -2
- package/src/tools/fetch.ts +33 -10
- package/src/tools/gh-cache-invalidation.ts +63 -8
- package/src/tools/gh-renderer.ts +1 -1
- package/src/tools/gh.ts +172 -29
- package/src/tools/github-cache.ts +70 -6
- package/src/tools/image-gen.ts +3 -9
- package/src/tools/irc.ts +5 -1
- package/src/tools/job.ts +1 -1
- package/src/tools/read.ts +202 -61
- package/src/tools/render-utils.ts +3 -3
- package/src/tools/resolve.ts +1 -1
- package/src/tools/search.ts +92 -29
- package/src/tools/sqlite-reader.ts +17 -5
- package/src/tools/ssh.ts +8 -8
- package/src/tools/todo.ts +51 -12
- package/src/tools/write.ts +118 -18
- package/src/tui/output-block.ts +4 -4
- package/src/utils/changelog.ts +27 -1
- package/src/utils/file-mentions.ts +2 -1
- package/src/web/scrapers/arxiv.ts +1 -1
- package/src/web/scrapers/go-pkg.ts +1 -1
- package/src/web/scrapers/iacr.ts +1 -1
- package/src/web/scrapers/readthedocs.ts +1 -1
- package/src/web/scrapers/twitter.ts +2 -1
- package/src/web/scrapers/types.ts +87 -8
- package/src/web/scrapers/wikipedia.ts +1 -1
- package/src/web/scrapers/youtube.ts +6 -1
- package/src/web/search/index.ts +1 -1
- package/src/web/search/providers/anthropic.ts +8 -2
- package/src/web/search/providers/codex.ts +2 -1
- package/src/web/search/providers/gemini.ts +2 -3
- package/src/web/search/render.ts +8 -6
- package/dist/types/config/model-equivalence.d.ts +0 -24
- package/dist/types/config/model-id-affixes.d.ts +0 -12
- package/dist/types/config/model-provider-priority.d.ts +0 -1
- package/dist/types/exec/idle-timeout-watchdog.d.ts +0 -18
- package/src/config/model-equivalence.ts +0 -875
- package/src/config/model-id-affixes.ts +0 -81
- package/src/config/model-provider-priority.ts +0 -56
- package/src/exec/idle-timeout-watchdog.ts +0 -126
package/src/eval/py/runner.py
CHANGED
|
@@ -51,8 +51,23 @@ from typing import Any
|
|
|
51
51
|
# Frame writer
|
|
52
52
|
# ---------------------------------------------------------------------------
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
# Frames travel on a private dup of the original stdout. fd 1 itself is then
|
|
55
|
+
# repointed at a capture pipe: child processes spawned by user code without
|
|
56
|
+
# stdout=PIPE inherit fd 1, and their output is forwarded to the host as
|
|
57
|
+
# regular stdout frames by a drain thread instead of being written raw into
|
|
58
|
+
# the NDJSON channel (where it would be dropped as invalid JSON — or worse,
|
|
59
|
+
# spoof a frame). The wire protocol is unchanged: the host still reads NDJSON
|
|
60
|
+
# frames from the subprocess stdout.
|
|
55
61
|
_RAW_STDERR = sys.__stderr__
|
|
62
|
+
try:
|
|
63
|
+
_FRAME_FD = os.dup(sys.__stdout__.fileno())
|
|
64
|
+
_RAW_STDOUT = os.fdopen(_FRAME_FD, "w", encoding="utf-8", errors="backslashreplace")
|
|
65
|
+
_CAPTURE_READ_FD, _capture_write_fd = os.pipe()
|
|
66
|
+
os.dup2(_capture_write_fd, sys.__stdout__.fileno())
|
|
67
|
+
os.close(_capture_write_fd)
|
|
68
|
+
except (AttributeError, OSError, ValueError, io.UnsupportedOperation):
|
|
69
|
+
_RAW_STDOUT = sys.__stdout__
|
|
70
|
+
_CAPTURE_READ_FD = None
|
|
56
71
|
_OUT_LOCK = threading.Lock()
|
|
57
72
|
|
|
58
73
|
|
|
@@ -78,11 +93,22 @@ def _emit(frame: dict) -> None:
|
|
|
78
93
|
|
|
79
94
|
|
|
80
95
|
class _StreamProxy(io.TextIOBase):
|
|
81
|
-
"""Emit
|
|
96
|
+
"""Emit ``write()`` data as typed frames tied to the current request.
|
|
97
|
+
|
|
98
|
+
Writes are coalesced per request: a frame is emitted once the buffer holds
|
|
99
|
+
a complete line (everything up to the last newline goes out together) or
|
|
100
|
+
grows past ``_MAX_BUFFER`` bytes, so the common ``print()`` pair of
|
|
101
|
+
``write(text)`` + ``write("\\n")`` costs one frame instead of two. Partial
|
|
102
|
+
lines are bounded by ``flush()`` and the end-of-request flush.
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
_MAX_BUFFER = 8192
|
|
82
106
|
|
|
83
107
|
def __init__(self, kind: str) -> None:
|
|
84
108
|
super().__init__()
|
|
85
109
|
self._kind = kind
|
|
110
|
+
self._lock = threading.Lock()
|
|
111
|
+
self._buffers: dict[str, str] = {}
|
|
86
112
|
|
|
87
113
|
def writable(self) -> bool: # noqa: D401 - protocol method
|
|
88
114
|
return True
|
|
@@ -100,12 +126,44 @@ class _StreamProxy(io.TextIOBase):
|
|
|
100
126
|
_RAW_STDERR.write(data)
|
|
101
127
|
_RAW_STDERR.flush()
|
|
102
128
|
return len(data)
|
|
103
|
-
|
|
129
|
+
emit_text = None
|
|
130
|
+
with self._lock:
|
|
131
|
+
buf = self._buffers.pop(rid, "") + data
|
|
132
|
+
if len(buf) >= self._MAX_BUFFER:
|
|
133
|
+
emit_text = buf
|
|
134
|
+
else:
|
|
135
|
+
nl = buf.rfind("\n")
|
|
136
|
+
if nl >= 0:
|
|
137
|
+
emit_text = buf[: nl + 1]
|
|
138
|
+
rest = buf[nl + 1 :]
|
|
139
|
+
if rest:
|
|
140
|
+
self._buffers[rid] = rest
|
|
141
|
+
else:
|
|
142
|
+
self._buffers[rid] = buf
|
|
143
|
+
if emit_text:
|
|
144
|
+
_emit({"type": self._kind, "id": rid, "data": emit_text})
|
|
104
145
|
return len(data)
|
|
105
146
|
|
|
106
147
|
def flush(self) -> None: # noqa: D401 - protocol method
|
|
148
|
+
rid = _CURRENT_RID.get()
|
|
149
|
+
if rid is not None:
|
|
150
|
+
self.flush_rid(rid)
|
|
107
151
|
return None
|
|
108
152
|
|
|
153
|
+
def flush_rid(self, rid: str) -> None:
|
|
154
|
+
"""Flush any buffered partial line for ``rid`` as its own frame."""
|
|
155
|
+
with self._lock:
|
|
156
|
+
buf = self._buffers.pop(rid, None)
|
|
157
|
+
if buf:
|
|
158
|
+
_emit({"type": self._kind, "id": rid, "data": buf})
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _flush_stream_proxies(rid: str) -> None:
|
|
162
|
+
"""Drain buffered proxy output for ``rid`` (called before its done frame)."""
|
|
163
|
+
for stream in (sys.stdout, sys.stderr):
|
|
164
|
+
if isinstance(stream, _StreamProxy):
|
|
165
|
+
stream.flush_rid(rid)
|
|
166
|
+
|
|
109
167
|
|
|
110
168
|
# ---------------------------------------------------------------------------
|
|
111
169
|
# Runner state
|
|
@@ -125,6 +183,10 @@ class _RunnerState:
|
|
|
125
183
|
self.last_install_marker: int = 0
|
|
126
184
|
self.loop: asyncio.AbstractEventLoop | None = None
|
|
127
185
|
self.active_executions: int = 0
|
|
186
|
+
# Best-effort attribution target for captured fd-1 bytes (child
|
|
187
|
+
# processes inheriting stdout). With overlapping requests the most
|
|
188
|
+
# recently started one wins — strictly better than dropping the bytes.
|
|
189
|
+
self.capture_rid: str | None = None
|
|
128
190
|
|
|
129
191
|
|
|
130
192
|
_CURRENT_RID: contextvars.ContextVar[str | None] = contextvars.ContextVar("omp_current_rid", default=None)
|
|
@@ -132,6 +194,42 @@ _CURRENT_RID: contextvars.ContextVar[str | None] = contextvars.ContextVar("omp_c
|
|
|
132
194
|
_STATE = _RunnerState()
|
|
133
195
|
|
|
134
196
|
|
|
197
|
+
def _drain_captured_stdout() -> None:
|
|
198
|
+
"""Forward bytes written to the captured fd 1 as stdout frames.
|
|
199
|
+
|
|
200
|
+
Runs on a daemon thread for the life of the process. Child processes that
|
|
201
|
+
inherit fd 1 (any ``subprocess`` call without ``stdout=PIPE``) land here.
|
|
202
|
+
"""
|
|
203
|
+
if _CAPTURE_READ_FD is None:
|
|
204
|
+
return
|
|
205
|
+
import codecs
|
|
206
|
+
|
|
207
|
+
decoder = codecs.getincrementaldecoder("utf-8")("replace")
|
|
208
|
+
while True:
|
|
209
|
+
try:
|
|
210
|
+
chunk = os.read(_CAPTURE_READ_FD, 65536)
|
|
211
|
+
except OSError:
|
|
212
|
+
return
|
|
213
|
+
if not chunk:
|
|
214
|
+
return
|
|
215
|
+
text = decoder.decode(chunk)
|
|
216
|
+
if not text:
|
|
217
|
+
continue
|
|
218
|
+
rid = _STATE.capture_rid
|
|
219
|
+
if rid is None:
|
|
220
|
+
_RAW_STDERR.write(text)
|
|
221
|
+
_RAW_STDERR.flush()
|
|
222
|
+
else:
|
|
223
|
+
_emit({"type": "stdout", "id": rid, "data": text})
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def _start_capture_drain() -> None:
|
|
227
|
+
if _CAPTURE_READ_FD is None:
|
|
228
|
+
return
|
|
229
|
+
thread = threading.Thread(target=_drain_captured_stdout, name="omp-fd1-capture", daemon=True)
|
|
230
|
+
thread.start()
|
|
231
|
+
|
|
232
|
+
|
|
135
233
|
# ---------------------------------------------------------------------------
|
|
136
234
|
# Magic source transformer
|
|
137
235
|
# ---------------------------------------------------------------------------
|
|
@@ -880,6 +978,7 @@ def _start_parent_watchdog() -> None:
|
|
|
880
978
|
async def _handle_request_async(req: dict) -> None:
|
|
881
979
|
rid = str(req.get("id"))
|
|
882
980
|
token = _CURRENT_RID.set(rid)
|
|
981
|
+
_STATE.capture_rid = rid
|
|
883
982
|
_STATE.user_ns["__omp_run_id__"] = rid
|
|
884
983
|
_STATE.cancel_requested = False
|
|
885
984
|
_STATE.execution_count += 1
|
|
@@ -934,6 +1033,7 @@ async def _handle_request_async(req: dict) -> None:
|
|
|
934
1033
|
except Exception:
|
|
935
1034
|
pass
|
|
936
1035
|
|
|
1036
|
+
_flush_stream_proxies(rid)
|
|
937
1037
|
_emit({
|
|
938
1038
|
"type": "done",
|
|
939
1039
|
"id": rid,
|
|
@@ -942,6 +1042,9 @@ async def _handle_request_async(req: dict) -> None:
|
|
|
942
1042
|
"cancelled": cancelled,
|
|
943
1043
|
})
|
|
944
1044
|
finally:
|
|
1045
|
+
if _STATE.capture_rid == rid:
|
|
1046
|
+
_STATE.capture_rid = None
|
|
1047
|
+
_flush_stream_proxies(rid)
|
|
945
1048
|
_CURRENT_RID.reset(token)
|
|
946
1049
|
|
|
947
1050
|
|
|
@@ -986,6 +1089,7 @@ async def _main_async() -> None:
|
|
|
986
1089
|
sys.stderr = _StreamProxy("stderr")
|
|
987
1090
|
_install_idle_sigint()
|
|
988
1091
|
_start_parent_watchdog()
|
|
1092
|
+
_start_capture_drain()
|
|
989
1093
|
|
|
990
1094
|
stdin = sys.__stdin__
|
|
991
1095
|
if stdin is None:
|
|
@@ -314,7 +314,9 @@ export async function executeBash(command: string, options?: BashExecutorOptions
|
|
|
314
314
|
if (userSignal) {
|
|
315
315
|
userSignal.removeEventListener("abort", abortHandler);
|
|
316
316
|
}
|
|
317
|
-
if (resetSession) {
|
|
317
|
+
if (resetSession || options?.sessionKey?.includes(":async:")) {
|
|
318
|
+
// `:async:` keys are per-job (jobId is unique), so the Shell would
|
|
319
|
+
// otherwise stay in the process-global map forever after completion.
|
|
318
320
|
shellSessions.delete(sessionKey);
|
|
319
321
|
}
|
|
320
322
|
}
|