friday-sh 0.1.0__tar.gz

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.
Files changed (79) hide show
  1. friday_sh-0.1.0/.github/workflows/ci.yml +42 -0
  2. friday_sh-0.1.0/.github/workflows/release.yml +106 -0
  3. friday_sh-0.1.0/.gitignore +15 -0
  4. friday_sh-0.1.0/.gitmodules +3 -0
  5. friday_sh-0.1.0/.python-version +1 -0
  6. friday_sh-0.1.0/.rumdl.toml +73 -0
  7. friday_sh-0.1.0/CLAUDE.md +52 -0
  8. friday_sh-0.1.0/PKG-INFO +420 -0
  9. friday_sh-0.1.0/README.md +402 -0
  10. friday_sh-0.1.0/TODO.md +105 -0
  11. friday_sh-0.1.0/docs/architecture.md +286 -0
  12. friday_sh-0.1.0/pyproject.toml +88 -0
  13. friday_sh-0.1.0/src/friday/__init__.py +3 -0
  14. friday_sh-0.1.0/src/friday/__main__.py +5 -0
  15. friday_sh-0.1.0/src/friday/agent/__init__.py +0 -0
  16. friday_sh-0.1.0/src/friday/agent/context.py +102 -0
  17. friday_sh-0.1.0/src/friday/agent/contracts.py +52 -0
  18. friday_sh-0.1.0/src/friday/agent/core.py +602 -0
  19. friday_sh-0.1.0/src/friday/agent/deps.py +30 -0
  20. friday_sh-0.1.0/src/friday/agent/history.py +110 -0
  21. friday_sh-0.1.0/src/friday/agent/memory.py +167 -0
  22. friday_sh-0.1.0/src/friday/agent/modes.py +60 -0
  23. friday_sh-0.1.0/src/friday/agent/prompts/code.md +40 -0
  24. friday_sh-0.1.0/src/friday/agent/prompts/debug.md +42 -0
  25. friday_sh-0.1.0/src/friday/agent/prompts/reader.md +47 -0
  26. friday_sh-0.1.0/src/friday/agent/prompts/router.md +79 -0
  27. friday_sh-0.1.0/src/friday/agent/prompts/writer.md +42 -0
  28. friday_sh-0.1.0/src/friday/agent/router.py +65 -0
  29. friday_sh-0.1.0/src/friday/agent/stats.py +194 -0
  30. friday_sh-0.1.0/src/friday/cli/__init__.py +0 -0
  31. friday_sh-0.1.0/src/friday/cli/app.py +336 -0
  32. friday_sh-0.1.0/src/friday/cli/ask.py +70 -0
  33. friday_sh-0.1.0/src/friday/cli/catalog.py +61 -0
  34. friday_sh-0.1.0/src/friday/cli/chat.py +686 -0
  35. friday_sh-0.1.0/src/friday/cli/completer.py +156 -0
  36. friday_sh-0.1.0/src/friday/cli/confirm.py +52 -0
  37. friday_sh-0.1.0/src/friday/cli/debug.py +86 -0
  38. friday_sh-0.1.0/src/friday/cli/models.py +89 -0
  39. friday_sh-0.1.0/src/friday/cli/output.py +52 -0
  40. friday_sh-0.1.0/src/friday/cli/picker.py +208 -0
  41. friday_sh-0.1.0/src/friday/cli/resources.py +219 -0
  42. friday_sh-0.1.0/src/friday/cli/theme.py +82 -0
  43. friday_sh-0.1.0/src/friday/domain/__init__.py +0 -0
  44. friday_sh-0.1.0/src/friday/domain/models.py +94 -0
  45. friday_sh-0.1.0/src/friday/domain/permissions.py +93 -0
  46. friday_sh-0.1.0/src/friday/domain/validation.py +51 -0
  47. friday_sh-0.1.0/src/friday/infra/__init__.py +0 -0
  48. friday_sh-0.1.0/src/friday/infra/config.py +95 -0
  49. friday_sh-0.1.0/src/friday/infra/mcp.py +72 -0
  50. friday_sh-0.1.0/src/friday/infra/memory.py +666 -0
  51. friday_sh-0.1.0/src/friday/infra/sessions.py +142 -0
  52. friday_sh-0.1.0/src/friday/infra/store.py +88 -0
  53. friday_sh-0.1.0/src/friday/shell/__init__.py +0 -0
  54. friday_sh-0.1.0/src/friday/shell/friday.plugin.zsh +136 -0
  55. friday_sh-0.1.0/src/friday/tools/__init__.py +0 -0
  56. friday_sh-0.1.0/src/friday/tools/filesystem.py +102 -0
  57. friday_sh-0.1.0/src/friday/tools/memory.py +103 -0
  58. friday_sh-0.1.0/src/friday/tools/registry.py +17 -0
  59. friday_sh-0.1.0/src/friday/tools/shell.py +49 -0
  60. friday_sh-0.1.0/tests/__init__.py +0 -0
  61. friday_sh-0.1.0/tests/conftest.py +20 -0
  62. friday_sh-0.1.0/tests/test_ask.py +58 -0
  63. friday_sh-0.1.0/tests/test_chat.py +212 -0
  64. friday_sh-0.1.0/tests/test_cli.py +149 -0
  65. friday_sh-0.1.0/tests/test_context.py +50 -0
  66. friday_sh-0.1.0/tests/test_core.py +388 -0
  67. friday_sh-0.1.0/tests/test_history.py +81 -0
  68. friday_sh-0.1.0/tests/test_memory.py +146 -0
  69. friday_sh-0.1.0/tests/test_models.py +37 -0
  70. friday_sh-0.1.0/tests/test_output.py +15 -0
  71. friday_sh-0.1.0/tests/test_permissions.py +46 -0
  72. friday_sh-0.1.0/tests/test_resources.py +44 -0
  73. friday_sh-0.1.0/tests/test_search_tool.py +54 -0
  74. friday_sh-0.1.0/tests/test_security.py +130 -0
  75. friday_sh-0.1.0/tests/test_shell_tool.py +76 -0
  76. friday_sh-0.1.0/tests/test_stats.py +126 -0
  77. friday_sh-0.1.0/tests/test_tools.py +99 -0
  78. friday_sh-0.1.0/ty.toml +21 -0
  79. friday_sh-0.1.0/uv.lock +3152 -0
@@ -0,0 +1,42 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ concurrency:
7
+ group: ci-${{ github.workflow }}-${{ github.ref }}
8
+ cancel-in-progress: true
9
+
10
+ jobs:
11
+ validate:
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ contents: read
15
+
16
+ steps:
17
+ - name: Check out repository
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Set up uv
21
+ uses: astral-sh/setup-uv@v6
22
+ with:
23
+ python-version: "3.13"
24
+ enable-cache: true
25
+
26
+ - name: Install dependencies
27
+ run: uv sync --frozen --group dev --group test
28
+
29
+ - name: Check formatting
30
+ run: uv run ruff format --check .
31
+
32
+ - name: Run lint
33
+ run: uv run ruff check .
34
+
35
+ - name: Run markdown lint
36
+ run: uvx rumdl check .
37
+
38
+ - name: Run type check
39
+ run: uv run ty check --exclude 'tests/'
40
+
41
+ - name: Run tests
42
+ run: uv run pytest -v
@@ -0,0 +1,106 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ workflow_dispatch:
8
+
9
+ concurrency:
10
+ group: release-${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: false
12
+
13
+ permissions:
14
+ contents: write
15
+ id-token: write
16
+
17
+ jobs:
18
+ release:
19
+ runs-on: ubuntu-latest
20
+ environment:
21
+ name: pypi
22
+ url: https://pypi.org/p/friday-sh
23
+
24
+ steps:
25
+ - name: Check out repository
26
+ uses: actions/checkout@v4
27
+ with:
28
+ fetch-depth: 0
29
+
30
+ - name: Set up uv
31
+ uses: astral-sh/setup-uv@v6
32
+ with:
33
+ python-version: "3.13"
34
+ enable-cache: true
35
+
36
+ - name: Install dependencies
37
+ run: uv sync --frozen --group dev --group test
38
+
39
+ - name: Run validation
40
+ run: |
41
+ uv run ruff format --check .
42
+ uv run ruff check .
43
+ uvx rumdl check .
44
+ uv run ty check --exclude 'tests/'
45
+ uv run pytest -v
46
+
47
+ - name: Read package version
48
+ id: version
49
+ run: |
50
+ VERSION=$(python - <<'PY'
51
+ from pathlib import Path
52
+ import tomllib
53
+
54
+ data = tomllib.loads(Path('pyproject.toml').read_text())
55
+ print(data['project']['version'])
56
+ PY
57
+ )
58
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
59
+ echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
60
+
61
+ - name: Check release state
62
+ id: state
63
+ env:
64
+ GH_TOKEN: ${{ github.token }}
65
+ run: |
66
+ TAG="${{ steps.version.outputs.tag }}"
67
+ if git ls-remote --tags origin "refs/tags/$TAG" | grep -q "$TAG"; then
68
+ echo "tag_exists=true" >> "$GITHUB_OUTPUT"
69
+ else
70
+ echo "tag_exists=false" >> "$GITHUB_OUTPUT"
71
+ fi
72
+
73
+ if gh release view "$TAG" >/dev/null 2>&1; then
74
+ echo "release_exists=true" >> "$GITHUB_OUTPUT"
75
+ else
76
+ echo "release_exists=false" >> "$GITHUB_OUTPUT"
77
+ fi
78
+
79
+ - name: Create release tag
80
+ if: steps.state.outputs.tag_exists != 'true'
81
+ run: |
82
+ TAG="${{ steps.version.outputs.tag }}"
83
+ git config user.name "github-actions[bot]"
84
+ git config user.email "github-actions[bot]@users.noreply.github.com"
85
+ git tag -a "$TAG" -m "release: $TAG"
86
+ git push origin "$TAG"
87
+
88
+ - name: Build distribution artifacts
89
+ run: uv build
90
+
91
+ - name: Publish to PyPI
92
+ uses: pypa/gh-action-pypi-publish@release/v1
93
+ with:
94
+ packages-dir: dist
95
+ skip-existing: true
96
+
97
+ - name: Create GitHub release
98
+ if: steps.state.outputs.release_exists != 'true'
99
+ env:
100
+ GH_TOKEN: ${{ github.token }}
101
+ run: |
102
+ TAG="${{ steps.version.outputs.tag }}"
103
+ gh release create "$TAG" \
104
+ --title "$TAG" \
105
+ --generate-notes \
106
+ --verify-tag
@@ -0,0 +1,15 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Environment
10
+ .env
11
+
12
+ # Virtual environments
13
+ .venv
14
+ .*_cache
15
+ .codex
@@ -0,0 +1,3 @@
1
+ [submodule ".claude"]
2
+ path = .claude
3
+ url = https://github.com/oornnery/.agents
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,73 @@
1
+ # rumdl configuration file
2
+
3
+ # Inherit settings from another config file (relative to this file's directory)
4
+ # extends = "../base.rumdl.toml"
5
+
6
+ # Global configuration options
7
+ [global]
8
+ # List of rules to disable (uncomment and modify as needed)
9
+ # disable = ["MD013", "MD033"]
10
+
11
+ # List of rules to enable exclusively (replaces defaults; only these rules will run)
12
+ # enable = ["MD001", "MD003", "MD004"]
13
+
14
+ # Additional rules to enable on top of defaults (additive, does not replace)
15
+ # Use this to activate opt-in rules like MD060, MD063, MD072, MD073, MD074
16
+ # extend-enable = ["MD060", "MD063"]
17
+
18
+ # Additional rules to disable on top of the disable list (additive)
19
+ # extend-disable = ["MD041"]
20
+
21
+ # List of file/directory patterns to include for linting (if provided, only these will be linted)
22
+ # include = [
23
+ # "docs/*.md",
24
+ # "src/**/*.md",
25
+ # "README.md"
26
+ # ]
27
+
28
+ # List of file/directory patterns to exclude from linting
29
+ exclude = [
30
+ # Common directories to exclude
31
+ ".git",
32
+ ".github",
33
+ "node_modules",
34
+ "vendor",
35
+ "dist",
36
+ "build",
37
+
38
+ # Specific files or patterns
39
+ "CHANGELOG.md",
40
+ "LICENSE.md",
41
+ ]
42
+
43
+ # Respect .gitignore files when scanning directories (default: true)
44
+ respect-gitignore = true
45
+
46
+ # Markdown flavor/dialect (uncomment to enable)
47
+ # Options: standard (default), gfm, commonmark, mkdocs, mdx, quarto
48
+ # flavor = "mkdocs"
49
+
50
+ # Rule-specific configurations (uncomment and modify as needed)
51
+
52
+ # [MD003]
53
+ # style = "atx" # Heading style (atx, atx_closed, setext)
54
+
55
+ # [MD004]
56
+ # style = "asterisk" # Unordered list style (asterisk, plus, dash, consistent)
57
+
58
+ # [MD007]
59
+ # indent = 4 # Unordered list indentation
60
+
61
+ [MD013]
62
+ line-length = 0 # Line length
63
+ # code-blocks = false # Exclude code blocks from line length check
64
+ # tables = false # Exclude tables from line length check
65
+ # headings = true # Include headings in line length check
66
+
67
+ # [MD044]
68
+ # names = ["rumdl", "Markdown", "GitHub"] # Proper names that should be capitalized correctly
69
+ # code-blocks = false # Check code blocks for proper names (default: false, skips code blocks)
70
+
71
+ [MD060]
72
+ enabled = true
73
+ style = "aligned"
@@ -0,0 +1,52 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Stack
6
+
7
+ - **Language**: Python 3.13
8
+ - **Package manager**: uv
9
+ - **Agent framework**: pydantic-ai
10
+ - **CLI**: typer + rich + prompt_toolkit
11
+ - **Linter/Formatter**: ruff
12
+ - **Test runner**: pytest
13
+ - **Task runner**: taskipy
14
+
15
+ ## Commands
16
+
17
+ ```bash
18
+ uv sync # Install deps
19
+ uv run task fmt # Format (ruff format)
20
+ uv run task lint # Lint (ruff check)
21
+ uv run task fix # Lint + autofix
22
+ uv run task test # Run tests
23
+ uv run task check # fmt + lint + test (full validation)
24
+ uv run pytest -v tests/path.py::test_name # Single test
25
+ ```
26
+
27
+ ## Architecture
28
+
29
+ ```text
30
+ src/friday/
31
+ ├── domain/ # Enums, value objects, permissions (pure, no IO)
32
+ ├── agent/ # pydantic-ai agent, modes, context, prompts/
33
+ ├── tools/ # Tool implementations (filesystem, shell)
34
+ ├── infra/ # Config, sessions, MCP client (IO boundary)
35
+ ├── cli/ # Typer app, commands, rich output
36
+ └── shell/ # ZSH plugin
37
+ ```
38
+
39
+ - **Prompts** live in `agent/prompts/*.md` with YAML frontmatter (tools, max_steps)
40
+ - **Modes** (code, reader, write, debug) are loaded from those .md files
41
+ - **z.ai** is wired as an OpenAI-compatible provider via `zai:` prefix
42
+ - **Config** merges: env vars (`FRIDAY_*`) > `.env` > `~/.config/friday/config.toml`
43
+
44
+ ## Conventions
45
+
46
+ See `.claude/rules/python.md` for full Python conventions. Key points:
47
+
48
+ - `pathlib` over `os.path`, f-strings only, type all public functions
49
+ - `logging` for app logs, `rich` for CLI output — never `print`
50
+ - IO at edges only — domain and services must be pure
51
+ - Prefer early returns over deep nesting
52
+ - `ruff check` must pass before any commit