fix(filesystem): package pifs cli entrypoint

This commit is contained in:
BukeLy 2026-05-26 14:38:39 +08:00
parent 574125d7dd
commit e074bf1765
5 changed files with 89 additions and 1 deletions

View file

@ -1,3 +1,7 @@
import os
os.environ.setdefault("LITELLM_LOCAL_MODEL_COST_MAP", "true")
try:
from .page_index import *
from .page_index_md import md_to_tree

View file

@ -16,6 +16,39 @@ DEFAULT_AGENT_MODEL = "gpt-5.4-mini"
EXIT_COMMANDS = {"exit", "quit", ":q"}
def _load_env_file(path: str | None = None, *, workspace: str | None = None) -> Path | None:
from dotenv import load_dotenv
if path:
env_path = Path(path).expanduser()
if not env_path.exists():
raise FileNotFoundError(f"env file not found: {env_path}")
load_dotenv(env_path, override=True)
return env_path
env_override = os.environ.get("PIFS_ENV_FILE")
if env_override:
return _load_env_file(env_override)
starts = [Path.cwd()]
if workspace:
starts.append(Path(workspace).expanduser())
seen: set[Path] = set()
for start in starts:
current = start.resolve() if start.exists() else start.resolve(strict=False)
if current.is_file():
current = current.parent
for parent in (current, *current.parents):
candidate = parent / ".env"
if candidate in seen:
continue
seen.add(candidate)
if candidate.exists():
load_dotenv(candidate, override=False)
return candidate
return None
def _agent_model_default() -> str:
return (
os.environ.get("PIFS_AGENT_MODEL")
@ -30,6 +63,7 @@ def _add_agent_arguments(
workspace_default: str | None,
) -> None:
parser.add_argument("--workspace", default=workspace_default)
parser.add_argument("--env-file", default=None)
parser.add_argument("--model", default=_agent_model_default())
parser.add_argument(
"--stream-mode",
@ -64,6 +98,9 @@ def _parse_agent_command(
if command_name == "ask":
parser.add_argument("question", nargs=argparse.REMAINDER)
args = parser.parse_args(argv)
_load_env_file(args.env_file, workspace=args.workspace)
if not args.workspace:
args.workspace = os.environ.get("PIFS_WORKSPACE")
if not args.workspace:
parser.error("--workspace is required unless PIFS_WORKSPACE is set")
return args
@ -130,11 +167,16 @@ def _run_passthrough(
def main(argv: list[str] | None = None) -> int:
argv = list(sys.argv[1:] if argv is None else argv)
_load_env_file()
parser = argparse.ArgumentParser(description="PageIndex FileSystem CLI")
parser.add_argument("--workspace", default=os.environ.get("PIFS_WORKSPACE"))
parser.add_argument("--env-file", default=None)
parser.add_argument("--json", action="store_true", dest="json_output")
parser.add_argument("command", nargs=argparse.REMAINDER)
args = parser.parse_args(argv)
_load_env_file(args.env_file, workspace=args.workspace)
if not args.workspace:
args.workspace = os.environ.get("PIFS_WORKSPACE")
command_tokens = [token for token in args.command if token != "--"]
json_output = args.json_output

View file

@ -15,3 +15,10 @@ dependencies = [
[project.scripts]
pifs = "pageindex.filesystem.cli:main"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["pageindex"]

View file

@ -1,3 +1,4 @@
import os
from pathlib import Path
@ -87,6 +88,40 @@ def test_cli_ask_invokes_agent_with_question(monkeypatch, capsys, tmp_path):
}
def test_cli_ask_loads_env_file_before_running_agent(monkeypatch, capsys, tmp_path):
from pageindex.filesystem import cli
workspace = tmp_path / "workspace"
env_file = tmp_path / ".env"
env_file.write_text("OPENAI_API_KEY=from-dotenv\n", encoding="utf-8")
agent_keys = []
def fake_run_pifs_agent(filesystem, question, **kwargs):
agent_keys.append(os.environ.get("OPENAI_API_KEY"))
return "agent answer"
monkeypatch.delenv("OPENAI_API_KEY", raising=False)
monkeypatch.setattr(cli, "PageIndexFileSystem", FakeFileSystem)
monkeypatch.setattr(cli, "run_pifs_agent", fake_run_pifs_agent)
status = cli.main(
[
"ask",
"--workspace",
str(workspace),
"--env-file",
str(env_file),
"What",
"is",
"inside?",
]
)
assert status == 0
assert capsys.readouterr().out == "agent answer\n"
assert agent_keys == ["from-dotenv"]
def test_cli_chat_runs_one_question_and_exits(monkeypatch, capsys, tmp_path):
from pageindex.filesystem import cli

2
uv.lock generated
View file

@ -1048,7 +1048,7 @@ wheels = [
[[package]]
name = "pageindex"
version = "0.1.0"
source = { virtual = "." }
source = { editable = "." }
dependencies = [
{ name = "litellm" },
{ name = "openai-agents" },