Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
b5fdf68
Add EasyAtCal design spec
Ailcope Apr 19, 2026
b240c5d
Add EasyAtCal implementation plan
Ailcope Apr 19, 2026
8cdf321
scaffold: project layout, pyproject, gitignore, readme
Ailcope Apr 19, 2026
d869748
feat(models): Shift dataclass with tz-aware validation
Ailcope Apr 19, 2026
242ba39
feat(config): pydantic config loader with env overrides
Ailcope Apr 19, 2026
fcd0f8d
feat(state): atomic json state with corrupt-file recovery + updated_at
Ailcope Apr 19, 2026
6488db9
feat(api): OAuth auth + fetch_shifts with pagination and backoff
Ailcope Apr 19, 2026
753f4d9
feat(sync): backend protocol + diff engine for adds/updates/deletes
Ailcope Apr 19, 2026
4f209a9
feat(backends): ICS file backend with add/update/delete
Ailcope Apr 19, 2026
0348ce8
feat(backends): macOS EventKit backend via pyobjc
Ailcope Apr 19, 2026
64c7ded
feat(orchestrator): tie api + sync + backend + state together
Ailcope Apr 19, 2026
d28cd08
feat(cli): config/sync/watch/auth commands with logging
Ailcope Apr 19, 2026
e3ec355
ci+e2e: GitHub Actions matrix + end-to-end ICS test
Ailcope Apr 19, 2026
19c2ca4
docs: add HANDOFF.md with full context file list
Ailcope Apr 19, 2026
5c355f9
chore: add MIT LICENSE
Ailcope Apr 19, 2026
13e0bb6
feat: atomic state sync via ApplyResult + BackendError
Ailcope Apr 19, 2026
8085ca9
feat: add doctor command for config/auth/backend checks
Ailcope Apr 19, 2026
1ddcd09
ci: publish to PyPI via trusted publisher on tag push
Ailcope Apr 19, 2026
47c78cc
feat(cli): add --dry-run flag to sync
Ailcope Apr 19, 2026
280c681
docs: expand README, add CHANGELOG, add launchd agent template
Ailcope Apr 19, 2026
34767f7
feat(cli): add state show command
Ailcope Apr 19, 2026
a7971ea
chore: add ruff config, pre-commit hooks, CI lint + 85% coverage gate
Ailcope Apr 19, 2026
3ddaa1e
feat: exit codes, sync summary, JSON log format
Ailcope Apr 19, 2026
06032ef
feat: SIGTERM handling in watch + Retry-After in API backoff
Ailcope Apr 19, 2026
4ef9835
feat(cli): global --config-path override + docs refresh
Ailcope Apr 19, 2026
6efa8d2
release: v0.2.0
Ailcope Apr 19, 2026
dd710a8
feat: state clear, doctor writable check, dependabot
Ailcope Apr 19, 2026
7eb0a26
docs+dx: add CONTRIBUTING, SECURITY, Makefile
Ailcope Apr 19, 2026
7d47cb8
chore: OSS polish — issue/PR templates, editorconfig, README badges
Ailcope Apr 19, 2026
38fe642
feat: handle high value tasks from backlog
Ailcope Apr 19, 2026
5d6a618
feat: add --verbose and --quiet CLI log level overrides
Ailcope Apr 19, 2026
92addd9
feat: add robust api parsing and systemd template
Ailcope Apr 19, 2026
5c25fd9
feat: mypy strict, structured logging, docker, mkdocs site
Ailcope Apr 20, 2026
323f338
feat: session-cookie auth via headless Playwright browser
Ailcope Apr 20, 2026
48cb8b0
feat(auth): switch user-mode auth to Bearer JWT against regional API
Ailcope Apr 20, 2026
8d90cf4
docs: refactor interactive CLI prompts and README language
Ailcope Apr 20, 2026
90df040
docs: restyle and center README layout
Ailcope Apr 20, 2026
b5fd92d
chore: fix mypy typing errors in CI and upgrade README badges
Ailcope Apr 20, 2026
c21efe4
ci: bump actions/checkout from 4 to 6 (#1)
dependabot[bot] Apr 20, 2026
ed3a5cd
ci: bump actions/download-artifact from 4 to 8 (#3)
dependabot[bot] Apr 20, 2026
0c8ba46
ci: bump actions/upload-artifact from 4 to 7 (#4)
dependabot[bot] Apr 20, 2026
f79f8d5
docs: fix markdown parsing inside div for MkDocs
Ailcope Apr 20, 2026
7eb29c5
ci: add ruff to dev dependencies to fix missing command in pipeline
Ailcope Apr 20, 2026
ff4aa0f
feat: Automate extraction, caching, scheduling and alarms
Ailcope Apr 20, 2026
1a3a911
docs: improve SEO with easy@work explanation and notable clients
Ailcope Apr 20, 2026
abaf220
test: add schedule command test coverage
Ailcope Apr 20, 2026
aa834fc
chore: bump version to v0.3.0 for feature release
Ailcope Apr 20, 2026
a574cb4
fix: resolve ruff lint errors in tests and core files
Ailcope Apr 20, 2026
8efba0d
docs: update security contact email to security@ailcope.dev
Ailcope Apr 20, 2026
b2d7766
fix: mock keyring in api tests and store user preferences
Ailcope Apr 20, 2026
5c86e1c
fix: add dtstamp and calscale to ics events to fix apple calendar import
Ailcope Apr 20, 2026
0ecc1dc
fix: apple calendar ics event requirements and mock keyring
Ailcope Apr 20, 2026
adb2d96
fix: populate full shift list for ics backend to avoid empty files an…
Ailcope Apr 20, 2026
d297897
feat: extract and map address from schedule.customer to shift location
Ailcope Apr 20, 2026
1f7fc55
fix: use current time for dtstamp and sequence in ics to force apple …
Ailcope Apr 20, 2026
9f2d48a
feat: enrich ics file with universal client compatibility tags (outlo…
Ailcope Apr 20, 2026
bf167a1
feat: bilingual configuration wizard with french language support
Ailcope Apr 20, 2026
a74094d
chore: remove leaked HAR captures and scratch file, ignore *.har
Ailcope May 22, 2026
25b72bb
refactor: dedup french detection and drop redundant imports
Ailcope May 22, 2026
9c2da52
fix: raise on unrecognized shifts payload shape
Ailcope May 22, 2026
c17f0f0
test: run config init non-interactively in test
Ailcope May 22, 2026
7aad3d1
fix: preserve past shifts across syncs
Ailcope May 22, 2026
84e8deb
fix: stabilize sync migration and CI
Ailcope Jun 14, 2026
4c1feef
Relicense under PolyForm Noncommercial 1.0.0
Ailcope Jun 20, 2026
e3e3183
ci: bump actions/configure-pages from 5 to 6 (#5)
dependabot[bot] Jun 20, 2026
a7dab58
ci: bump actions/deploy-pages from 4 to 5 (#6)
dependabot[bot] Jun 20, 2026
16bffe6
ci: bump actions/upload-pages-artifact from 3 to 5 (#7)
dependabot[bot] Jun 20, 2026
d60586a
ci: bump actions/checkout from 6 to 7
dependabot[bot] Jun 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.git
.gitignore
.venv
__pycache__
*.pyc
.pytest_cache
.ruff_cache
.coverage
tests
docs
site
18 changes: 18 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space

[*.py]
indent_size = 4
max_line_length = 100

[*.{yml,yaml,toml,json,md}]
indent_size = 2

[Makefile]
indent_style = tab
45 changes: 45 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Bug report
description: Something is broken.
labels: ["bug"]
body:
- type: textarea
id: what
attributes:
label: What happened
description: Describe the bug and what you expected instead.
validations:
required: true
- type: textarea
id: repro
attributes:
label: Reproduction
description: Minimal steps to reproduce.
validations:
required: true
- type: textarea
id: doctor
attributes:
label: Output of `eaw-sync doctor`
render: shell
validations:
required: true
- type: input
id: version
attributes:
label: Version
description: "`eaw-sync --version`"
validations:
required: true
- type: input
id: os
attributes:
label: OS
description: e.g. macOS 14.4, Ubuntu 22.04
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log excerpt
description: Redact any tokens.
render: shell
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Security vulnerability
url: https://github.com/Ailcope/EasyAtCal/blob/main/SECURITY.md
about: Do not file a public issue — see SECURITY.md for the disclosure channel.
22 changes: 22 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Feature request
description: Suggest a change that fits the project scope.
labels: ["enhancement"]
body:
- type: textarea
id: problem
attributes:
label: Problem
description: What are you trying to do that EasyAtCal makes hard?
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposal
description: What should change, roughly? CLI surface, config, behavior.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
commit-message:
prefix: "deps"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "ci"
18 changes: 18 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## What

<!-- One-paragraph summary. Link any related issue. -->

## Why

<!-- The problem this solves or the behavior it changes. -->

## How

<!-- Brief notes on the approach; non-obvious decisions. -->

## Checklist

- [ ] Tests added or updated; `make check` passes locally.
- [ ] CHANGELOG `[Unreleased]` entry added (if user-visible).
- [ ] No `Co-Authored-By` trailers.
- [ ] If it touches the CLI surface, README is updated.
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CI

on:
push:
branches: [main]
pull_request:

jobs:
test:
strategy:
fail-fast: false
matrix:
python: ["3.11", "3.12"]
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
cache: pip
- name: Install
run: |
python -m pip install --upgrade pip
pip install -e '.[dev]'
- name: Install eventkit extra (macOS only)
if: runner.os == 'macOS'
run: pip install -e '.[eventkit]'
- name: Lint
run: ruff check easyatcal tests
- name: Types
run: mypy easyatcal
- name: Test
run: pytest --cov=easyatcal --cov-fail-under=85
49 changes: 49 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Docs
on:
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install mkdocs-material
- name: Copy files
run: |
mkdir -p docs/pages
cp README.md docs/pages/index.md
cp CONTRIBUTING.md docs/pages/contributing.md
cp CHANGELOG.md docs/pages/changelog.md
- name: Build docs
run: mkdocs build
- name: Setup Pages
uses: actions/configure-pages@v6
- name: Upload artifact
uses: actions/upload-pages-artifact@v5
with:
path: 'site'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
42 changes: 42 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Publish to PyPI

on:
push:
tags:
- "v*"

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install build tooling
run: python -m pip install --upgrade build
- name: Build sdist and wheel
run: python -m build
- uses: actions/upload-artifact@v7
with:
name: dist
path: dist/

publish:
needs: build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/easyatcal
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v8
with:
name: dist
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Secrets & user data
config.yaml
.env
*.ics
*.har
state.json
token.json
.cache/

# Python
__pycache__/
*.py[cod]
*.egg-info/
.pytest_cache/
.coverage
htmlcov/
dist/
build/

# Editors / OS
.vscode/
.idea/
.DS_Store
.venv/
.claude/
16 changes: 16 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.9
hooks:
- id: ruff
args: [--fix]
- id: ruff-format

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-toml
- id: check-merge-conflict
Loading
Loading