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.
- friday_sh-0.1.0/.github/workflows/ci.yml +42 -0
- friday_sh-0.1.0/.github/workflows/release.yml +106 -0
- friday_sh-0.1.0/.gitignore +15 -0
- friday_sh-0.1.0/.gitmodules +3 -0
- friday_sh-0.1.0/.python-version +1 -0
- friday_sh-0.1.0/.rumdl.toml +73 -0
- friday_sh-0.1.0/CLAUDE.md +52 -0
- friday_sh-0.1.0/PKG-INFO +420 -0
- friday_sh-0.1.0/README.md +402 -0
- friday_sh-0.1.0/TODO.md +105 -0
- friday_sh-0.1.0/docs/architecture.md +286 -0
- friday_sh-0.1.0/pyproject.toml +88 -0
- friday_sh-0.1.0/src/friday/__init__.py +3 -0
- friday_sh-0.1.0/src/friday/__main__.py +5 -0
- friday_sh-0.1.0/src/friday/agent/__init__.py +0 -0
- friday_sh-0.1.0/src/friday/agent/context.py +102 -0
- friday_sh-0.1.0/src/friday/agent/contracts.py +52 -0
- friday_sh-0.1.0/src/friday/agent/core.py +602 -0
- friday_sh-0.1.0/src/friday/agent/deps.py +30 -0
- friday_sh-0.1.0/src/friday/agent/history.py +110 -0
- friday_sh-0.1.0/src/friday/agent/memory.py +167 -0
- friday_sh-0.1.0/src/friday/agent/modes.py +60 -0
- friday_sh-0.1.0/src/friday/agent/prompts/code.md +40 -0
- friday_sh-0.1.0/src/friday/agent/prompts/debug.md +42 -0
- friday_sh-0.1.0/src/friday/agent/prompts/reader.md +47 -0
- friday_sh-0.1.0/src/friday/agent/prompts/router.md +79 -0
- friday_sh-0.1.0/src/friday/agent/prompts/writer.md +42 -0
- friday_sh-0.1.0/src/friday/agent/router.py +65 -0
- friday_sh-0.1.0/src/friday/agent/stats.py +194 -0
- friday_sh-0.1.0/src/friday/cli/__init__.py +0 -0
- friday_sh-0.1.0/src/friday/cli/app.py +336 -0
- friday_sh-0.1.0/src/friday/cli/ask.py +70 -0
- friday_sh-0.1.0/src/friday/cli/catalog.py +61 -0
- friday_sh-0.1.0/src/friday/cli/chat.py +686 -0
- friday_sh-0.1.0/src/friday/cli/completer.py +156 -0
- friday_sh-0.1.0/src/friday/cli/confirm.py +52 -0
- friday_sh-0.1.0/src/friday/cli/debug.py +86 -0
- friday_sh-0.1.0/src/friday/cli/models.py +89 -0
- friday_sh-0.1.0/src/friday/cli/output.py +52 -0
- friday_sh-0.1.0/src/friday/cli/picker.py +208 -0
- friday_sh-0.1.0/src/friday/cli/resources.py +219 -0
- friday_sh-0.1.0/src/friday/cli/theme.py +82 -0
- friday_sh-0.1.0/src/friday/domain/__init__.py +0 -0
- friday_sh-0.1.0/src/friday/domain/models.py +94 -0
- friday_sh-0.1.0/src/friday/domain/permissions.py +93 -0
- friday_sh-0.1.0/src/friday/domain/validation.py +51 -0
- friday_sh-0.1.0/src/friday/infra/__init__.py +0 -0
- friday_sh-0.1.0/src/friday/infra/config.py +95 -0
- friday_sh-0.1.0/src/friday/infra/mcp.py +72 -0
- friday_sh-0.1.0/src/friday/infra/memory.py +666 -0
- friday_sh-0.1.0/src/friday/infra/sessions.py +142 -0
- friday_sh-0.1.0/src/friday/infra/store.py +88 -0
- friday_sh-0.1.0/src/friday/shell/__init__.py +0 -0
- friday_sh-0.1.0/src/friday/shell/friday.plugin.zsh +136 -0
- friday_sh-0.1.0/src/friday/tools/__init__.py +0 -0
- friday_sh-0.1.0/src/friday/tools/filesystem.py +102 -0
- friday_sh-0.1.0/src/friday/tools/memory.py +103 -0
- friday_sh-0.1.0/src/friday/tools/registry.py +17 -0
- friday_sh-0.1.0/src/friday/tools/shell.py +49 -0
- friday_sh-0.1.0/tests/__init__.py +0 -0
- friday_sh-0.1.0/tests/conftest.py +20 -0
- friday_sh-0.1.0/tests/test_ask.py +58 -0
- friday_sh-0.1.0/tests/test_chat.py +212 -0
- friday_sh-0.1.0/tests/test_cli.py +149 -0
- friday_sh-0.1.0/tests/test_context.py +50 -0
- friday_sh-0.1.0/tests/test_core.py +388 -0
- friday_sh-0.1.0/tests/test_history.py +81 -0
- friday_sh-0.1.0/tests/test_memory.py +146 -0
- friday_sh-0.1.0/tests/test_models.py +37 -0
- friday_sh-0.1.0/tests/test_output.py +15 -0
- friday_sh-0.1.0/tests/test_permissions.py +46 -0
- friday_sh-0.1.0/tests/test_resources.py +44 -0
- friday_sh-0.1.0/tests/test_search_tool.py +54 -0
- friday_sh-0.1.0/tests/test_security.py +130 -0
- friday_sh-0.1.0/tests/test_shell_tool.py +76 -0
- friday_sh-0.1.0/tests/test_stats.py +126 -0
- friday_sh-0.1.0/tests/test_tools.py +99 -0
- friday_sh-0.1.0/ty.toml +21 -0
- 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 @@
|
|
|
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
|