feat: Add various tools for document processing and management
- Introduced `docx-extractor` for extracting content and metadata from Word .docx files. - Added `docx2md` for converting Word .docx files to Markdown format. - Implemented `gpt` for generating text using OpenAI's GPT models. - Created `html2text` for converting HTML content to plain text. - Developed `mbox2eml` for converting MBOX mailbox files to individual .eml files. - Added `md2pdf` for converting Markdown files to PDF format. - Introduced `mdscraper` for combining text files into a single markdown document. - Created `pdf-extractor` for extracting content and metadata from PDF files. - Developed `pdf2md` for converting PDF files to Markdown format. - Implemented `protonmail` for managing ProtonMail emails via Bridge. - Added `schedule` for managing systemd timers and services. - Introduced `search` for managing searchable collections of files. - Added `text-extractor` for extracting content and metadata from text files. - Removed outdated recommendations document.
This commit is contained in:
@@ -47,9 +47,11 @@ def run_create(args: argparse.Namespace) -> int:
|
||||
print(f"Error: component '{name}' already exists in castle.yaml")
|
||||
return 1
|
||||
|
||||
project_dir = config.root / name
|
||||
components_dir = config.root / "components"
|
||||
components_dir.mkdir(exist_ok=True)
|
||||
project_dir = components_dir / name
|
||||
if project_dir.exists():
|
||||
print(f"Error: directory '{name}' already exists")
|
||||
print(f"Error: directory 'components/{name}' already exists")
|
||||
return 1
|
||||
|
||||
# Determine port for services
|
||||
@@ -80,7 +82,7 @@ def run_create(args: argparse.Namespace) -> int:
|
||||
run=RunPythonUvTool(
|
||||
runner="python_uv_tool",
|
||||
tool=name,
|
||||
cwd=name,
|
||||
cwd=f"components/{name}",
|
||||
env={f"{env_prefix}_DATA_DIR": f"/data/castle/{name}"},
|
||||
),
|
||||
expose=ExposeSpec(
|
||||
@@ -96,7 +98,7 @@ def run_create(args: argparse.Namespace) -> int:
|
||||
manifest = ComponentManifest(
|
||||
id=name,
|
||||
description=args.description or f"A castle {proj_type}",
|
||||
tool=ToolSpec(source=f"{name}/"),
|
||||
tool=ToolSpec(source=f"components/{name}/"),
|
||||
install=InstallSpec(path=PathInstallSpec(alias=name)),
|
||||
)
|
||||
else:
|
||||
@@ -114,7 +116,7 @@ def run_create(args: argparse.Namespace) -> int:
|
||||
print(f" Port: {port}")
|
||||
print(" Registered in castle.yaml")
|
||||
print("\nNext steps:")
|
||||
print(f" cd {name}")
|
||||
print(f" cd components/{name}")
|
||||
print(" uv sync")
|
||||
if proj_type == "service":
|
||||
print(f" uv run {name} # starts on port {port}")
|
||||
|
||||
@@ -14,8 +14,7 @@ def _get_project_dir(config: CastleConfig, project_name: str) -> Path:
|
||||
if project_name not in config.components:
|
||||
raise ValueError(f"Unknown component: {project_name}")
|
||||
manifest = config.components[project_name]
|
||||
cwd = manifest.run.working_dir if manifest.run else None
|
||||
working_dir = cwd or project_name
|
||||
working_dir = manifest.source_dir or project_name
|
||||
return config.root / working_dir
|
||||
|
||||
|
||||
@@ -59,8 +58,7 @@ def run_test(args: argparse.Namespace) -> int:
|
||||
# Run all
|
||||
all_passed = True
|
||||
for name, manifest in config.components.items():
|
||||
cwd = manifest.run.working_dir if manifest.run else None
|
||||
working_dir = cwd or name
|
||||
working_dir = manifest.source_dir or name
|
||||
project_dir = config.root / working_dir
|
||||
tests_dir = project_dir / "tests"
|
||||
if not tests_dir.exists():
|
||||
@@ -98,8 +96,7 @@ def run_lint(args: argparse.Namespace) -> int:
|
||||
# Run all
|
||||
all_passed = True
|
||||
for name, manifest in config.components.items():
|
||||
cwd = manifest.run.working_dir if manifest.run else None
|
||||
working_dir = cwd or name
|
||||
working_dir = manifest.source_dir or name
|
||||
project_dir = config.root / working_dir
|
||||
if not _has_pyproject(project_dir):
|
||||
continue
|
||||
|
||||
@@ -29,8 +29,7 @@ def run_info(args: argparse.Namespace) -> int:
|
||||
if getattr(args, "json", False):
|
||||
data = manifest.model_dump(exclude_none=True)
|
||||
# Include CLAUDE.md content if it exists
|
||||
cwd = manifest.run.working_dir if manifest.run else None
|
||||
claude_md = _find_claude_md(config.root, cwd or name)
|
||||
claude_md = _find_claude_md(config.root, manifest.source_dir or name)
|
||||
if claude_md:
|
||||
data["claude_md"] = claude_md
|
||||
print(json.dumps(data, indent=2))
|
||||
|
||||
@@ -28,8 +28,7 @@ def run_sync(args: argparse.Namespace) -> int:
|
||||
all_ok = True
|
||||
synced_dirs: set[Path] = set()
|
||||
for name, manifest in config.components.items():
|
||||
cwd = manifest.run.working_dir if manifest.run else None
|
||||
working_dir = cwd or name
|
||||
working_dir = manifest.source_dir or name
|
||||
project_dir = config.root / working_dir
|
||||
pyproject = project_dir / "pyproject.toml"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user