Files
wehub-resource-sync bcbd1bdb22
Integ / changes (push) Has been skipped
Pre-commit / pre-commit (push) Failing after 1s
CLI exit codes / changes (push) Has been skipped
Test (Install) / changes (push) Has been skipped
Test (Python) / changes (push) Has been skipped
Test (TypeScript) / changes (push) Has been skipped
CLI exit codes / cli-gate (push) Has been cancelled
Test (Install) / test-install-gate (push) Has been cancelled
Integ / integ-gate (push) Has been cancelled
Test (Python) / test-python-gate (push) Has been cancelled
Test (TypeScript) / test-typescript-gate (push) Has been cancelled
Test (Install) / python-minimal (3.12) (push) Has been cancelled
Test (Install) / python-minimal (3.11) (push) Has been cancelled
Test (Install) / python-extra (agno, mirage.agents.agno) (push) Has been cancelled
Test (Install) / python-extra (chroma, mirage.resource.chroma) (push) Has been cancelled
Test (Install) / python-extra (pdf, mirage.core.filetype.pdf) (push) Has been cancelled
Integ / integ (push) Has been cancelled
Integ / integ-database (push) Has been cancelled
Integ / integ-database-ts (push) Has been cancelled
Integ / integ-data (push) Has been cancelled
Integ / integ-ssh (push) Has been cancelled
Integ / integ-ssh-ts (push) Has been cancelled
Test (Python) / audit (push) Has been cancelled
Test (TypeScript) / test (push) Has been cancelled
Test (TypeScript) / python-fs-shim (push) Has been cancelled
CLI exit codes / Python CLI (push) Has been cancelled
CLI exit codes / TypeScript CLI (push) Has been cancelled
CLI exit codes / Cross-language snapshot interop (push) Has been cancelled
Test (Python) / test (push) Has been cancelled
Test (Python) / import-isolation (deepagents, openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Python) / import-isolation (deepagents, pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Integ / integ-ts (push) Has been cancelled
Integ / integ-fuse (push) Has been cancelled
Test (Install) / python-extra (databricks, mirage.resource.databricks_volume) (push) Has been cancelled
Test (Install) / python-extra (deepagents, mirage.agents.langchain) (push) Has been cancelled
Test (Install) / python-extra (email, mirage.resource.email) (push) Has been cancelled
Test (Install) / python-extra (fuse, mirage.fuse.mount) (push) Has been cancelled
Test (Install) / python-extra (hdf5, mirage.core.filetype.hdf5) (push) Has been cancelled
Test (Install) / python-extra (hf, mirage.resource.hf_buckets) (push) Has been cancelled
Test (Install) / python-extra (lancedb, mirage.resource.lancedb) (push) Has been cancelled
Test (Install) / python-extra (langfuse, mirage.resource.langfuse) (push) Has been cancelled
Test (Install) / python-extra (mongodb, mirage.resource.mongodb) (push) Has been cancelled
Test (Install) / python-extra (nextcloud, mirage.resource.nextcloud) (push) Has been cancelled
Test (Install) / python-extra (openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Install) / python-extra (openhands, mirage.agents.openhands, 3.12) (push) Has been cancelled
Test (Install) / python-extra (parquet, mirage.core.filetype.parquet) (push) Has been cancelled
Test (Install) / python-extra (postgres, mirage.resource.postgres) (push) Has been cancelled
Test (Install) / python-extra (pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Test (Install) / python-extra (qdrant, mirage.resource.qdrant) (push) Has been cancelled
Test (Install) / python-extra (redis, mirage.resource.redis) (push) Has been cancelled
Test (Install) / python-extra (s3, mirage.resource.s3) (push) Has been cancelled
Test (Install) / python-extra (ssh, mirage.resource.ssh) (push) Has been cancelled
Test (Install) / ts-minimal (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:44 +08:00

122 lines
4.9 KiB
Python

# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
from mirage.io.types import ByteSource, IOResult
from mirage.resource.history import HISTORY_PREFIX
from mirage.workspace.session.session import Session
from mirage.workspace.types import ExecutionNode
USAGE = ("history: usage: history [-c] [-d offset] [n] or "
"history -awrn [filename] or history -ps arg [arg...]\n")
OPTION_CHARS = "cdanrwsp"
def _usage_error(message: str) -> tuple[None, IOResult, ExecutionNode]:
err = (message + USAGE).encode()
io = IOResult(exit_code=2, stderr=err)
return None, io, ExecutionNode(command="history", exit_code=2, stderr=err)
def _parse_args(
args: list[str]) -> tuple[dict[str, object], list[str], str | None]:
"""Parse history builtin args the way bash getopt does.
Args:
args (list[str]): Raw tokens after the command name.
Returns:
tuple[dict[str, object], list[str], str | None]: Flags dict,
operand texts, and an error message (None when parsing
succeeded). Any dash-leading token is option-parsed, digits
included (`history -1` is an invalid option in bash); `--` or
the first operand ends option parsing, so `history -s rm -rf`
stores "rm -rf" as text. `-d` takes the rest of its token as
the offset when attached (`-d3`, and `-dc` deletes entry "c"),
otherwise the next token.
"""
flags: dict[str, object] = {}
texts: list[str] = []
options_done = False
i = 0
while i < len(args):
token = args[i]
if options_done or token == "-" or not token.startswith("-"):
texts.append(token)
options_done = True
elif token == "--":
options_done = True
else:
j = 1
while j < len(token):
ch = token[j]
if ch not in OPTION_CHARS:
return {}, [], f"history: -{ch}: invalid option\n"
flags[ch] = True
if ch == "d":
rest = token[j + 1:]
if rest:
flags["d"] = rest
elif i + 1 < len(args):
i += 1
flags["d"] = args[i]
else:
return ({}, [],
"history: -d: option requires an argument\n")
break
j += 1
i += 1
return flags, texts, None
async def handle_history(
registry,
args: list[str],
session: Session,
) -> tuple[ByteSource | None, IOResult, ExecutionNode]:
"""Dispatch the history shell builtin to the view mount.
GNU lookup order: builtins resolve before mount commands, so a
mount-local command named "history" can never shadow this one.
The actual semantics live on the /.bash_history view resource;
this handler only parses options and routes.
Args:
registry (MountRegistry): The workspace's mount registry.
args (list[str]): Raw builtin args (flags and counts).
session (Session): Calling session.
"""
flags, texts, error = _parse_args(args)
if error is not None:
return _usage_error(error)
try:
mount = registry.mount_for(HISTORY_PREFIX)
except ValueError:
err = b"history: not enabled for this workspace\n"
return None, IOResult(exit_code=1,
stderr=err), ExecutionNode(command="history",
exit_code=1,
stderr=err)
stream, io = await mount.execute_cmd("history", [],
texts,
flags,
cwd=session.cwd,
session_id=session.session_id)
# The view command always returns byte stderr, but io.stderr is typed
# as a ByteSource (a possible lazy stream); resolve it to bytes so the
# execution-tree node holds concrete stderr, never an unread stream.
stderr = await io.materialize_stderr()
return stream, io, ExecutionNode(command="history",
exit_code=io.exit_code,
stderr=stderr)