pushframe 5.0.2__tar.gz → 5.0.4__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.
- {pushframe-5.0.2 → pushframe-5.0.4}/.github/workflows/release.yml +9 -9
- {pushframe-5.0.2 → pushframe-5.0.4}/.github/workflows/tests.yml +2 -2
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/MILESTONES.md +25 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/PROJECT.md +2 -0
- pushframe-5.0.4/.planning/REQUIREMENTS.md +118 -0
- pushframe-5.0.4/.planning/ROADMAP.md +105 -0
- pushframe-5.0.4/.planning/STATE.md +22 -0
- pushframe-5.0.2/.planning/REQUIREMENTS.md → pushframe-5.0.4/.planning/milestones/v5.0-REQUIREMENTS.md +9 -0
- pushframe-5.0.4/.planning/state.json +32 -0
- pushframe-5.0.4/CHANGELOG.md +167 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/PKG-INFO +8 -3
- {pushframe-5.0.2 → pushframe-5.0.4}/README.md +6 -2
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/__init__.py +1 -1
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/cli.py +4 -6
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/google/bootstrap.py +61 -8
- {pushframe-5.0.2 → pushframe-5.0.4}/pyproject.toml +2 -1
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_cli_google_link.py +32 -7
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_version.py +2 -2
- {pushframe-5.0.2 → pushframe-5.0.4}/uv.lock +1 -1
- pushframe-5.0.2/.planning/STATE.md +0 -168
- pushframe-5.0.2/.planning/state.json +0 -28
- {pushframe-5.0.2 → pushframe-5.0.4}/.env.sample +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.freebuff/project-id +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.gitignore +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.gsd/dispatch-isolation-sentinel.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/RETROSPECTIVE.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/WINDOWS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/codebase/ARCHITECTURE.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/codebase/CONCERNS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/codebase/CONVENTIONS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/codebase/INTEGRATIONS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/codebase/STACK.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/codebase/STRUCTURE.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/codebase/TESTING.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/config.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/debug/knowledge-base.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/debug/login-475-null-creds.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/debug/resolved/cli-status-verbose-logging.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/debug/resolved/inspect-asset-null-fields.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/debug/resolved/select-asset-401-unauthorized.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-REQUIREMENTS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-ROADMAP.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-DISCUSSION-LOG.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-PATTERNS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-RESEARCH.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-REVIEW.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-DISCUSSION-LOG.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-LIVE-EVIDENCE.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-PATTERNS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-RESEARCH.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-REVIEW.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-DISCUSSION-LOG.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-PATTERNS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-RESEARCH.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-REVIEW.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-ROADMAP.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/.gitkeep +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-03-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-03-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-PATTERNS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-RESEARCH.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-REVIEW.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-SECURITY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-UAT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-REQUIREMENTS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-ROADMAP.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-DISCUSSION-LOG.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-PATTERNS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-REVIEW.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-SECURITY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-UAT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-DISCUSSION-LOG.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-PATTERNS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-RESEARCH.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-REVIEW.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-SECURITY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-03-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-03-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-DISCUSSION-LOG.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-PATTERNS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-REVIEW-FIX.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-REVIEW.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-SECURITY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-03-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-03-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-04-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-04-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-DISCUSSION-LOG.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-LIVE-FINDINGS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-PATTERNS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-RESEARCH.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-REVIEW-FIX.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-REVIEW.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/.gitkeep +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-RESEARCH.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-REVIEW-FIX.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-REVIEW.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/.gitkeep +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-03-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-03-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-04-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-04-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-DISCUSSION-LOG.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-LIVE-FINDINGS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-PATTERNS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-RESEARCH.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-SECURITY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-UAT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/COVERAGE.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-quick/260630-qs8-make-main-py-load-a-local-env-file-at-st/260630-qs8-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-quick/260630-qs8-make-main-py-load-a-local-env-file-at-st/260630-qs8-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-quick/260708-dt9-add-progress-feedback-to-aura-cli-sync-a/260708-dt9-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-quick/260708-dt9-add-progress-feedback-to-aura-cli-sync-a/260708-dt9-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-quick/260708-dt9-add-progress-feedback-to-aura-cli-sync-a/deferred-items.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-quick/260708-fyr-batch-refactor-of-sync-apply-write-path-/260708-fyr-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-quick/260708-fyr-batch-refactor-of-sync-apply-write-path-/260708-fyr-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-quick/260708-fyr-batch-refactor-of-sync-apply-write-path-/260708-fyr-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v2.0-quick/README.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-REQUIREMENTS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-ROADMAP.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-03-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-03-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-04-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-04-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-05-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-05-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-06-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-06-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-DISCUSSION-LOG.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-LIVE-FINDINGS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-PATTERNS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-REVIEW.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-REQUIREMENTS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-ROADMAP.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-03-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-03-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-DECISION-RECORD.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-DISCUSSION-LOG.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-LIVE-FINDINGS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/COVERAGE.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-DISCUSS-CHECKPOINT.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/17-google-link-album-selection/COVERAGE.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-03-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-03-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-RESEARCH.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-UAT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-VERIFICATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/19-debt-closeout/19-01-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/19-debt-closeout/19-01-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/19-debt-closeout/19-02-PLAN.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/19-debt-closeout/19-02-SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/19-debt-closeout/19-CONTEXT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/19-debt-closeout/19-RESEARCH.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/milestones/v4.0-phases/19-debt-closeout/19-VERIFICATION.md +0 -0
- /pushframe-5.0.2/.planning/ROADMAP.md → /pushframe-5.0.4/.planning/milestones/v5.0-ROADMAP.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/20-pushframe-rename-migration-repo-switch/20-SUMMARY.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/21-debian-package-apt-repo/21-01-PLAN.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/21-debian-package-apt-repo/21-01-SUMMARY.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/21-debian-package-apt-repo/21-02-PLAN.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/21-debian-package-apt-repo/21-02-SUMMARY.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/21-debian-package-apt-repo/21-CONTEXT.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/21-debian-package-apt-repo/21-RESEARCH.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/21-debian-package-apt-repo/21-VERIFICATION.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/22-pypi-release-engineering/22-01-PLAN.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/22-pypi-release-engineering/22-01-SUMMARY.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/22-pypi-release-engineering/22-02-PLAN.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/22-pypi-release-engineering/22-02-SUMMARY.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/22-pypi-release-engineering/22-CONTEXT.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/22-pypi-release-engineering/22-RESEARCH.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/22-pypi-release-engineering/22-VERIFICATION.md +0 -0
- {pushframe-5.0.2/.planning/phases → pushframe-5.0.4/.planning/milestones/v5.0-phases}/22-pypi-release-engineering/OPERATOR-STEPS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/research/ALBUM-ACCESS-V4-ADDENDUM.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/research/ALBUM-ACCESS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/research/ARCHITECTURE.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/research/BROWSER-AUTOMATION.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/research/FEATURES.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/research/PITFALLS.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/research/STACK.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/research/SUMMARY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.planning/todos/completed/2026-07-06-promote-debug-flag-to-a-global-cli-convention.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/.python-version +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/CLAUDE.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/LICENSE +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/SECURITY.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/VERIFICATION-REPORT.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/docs/CLI.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/docs/agents/domain.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/docs/agents/issue-tracker.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/docs/agents/triage-labels.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/docs/superpowers/specs/2026-07-09-write-rate-limiter-design.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/main.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/packaging/control-template +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/packaging/lintian-overrides +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/packaging/postinst +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/packaging/pushframe.copyright +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/probes/.gitignore +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/probes/README.md +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/probes/browser_bootstrap.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/probes/common.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/probes/cookie_vault.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/probes/fidelity_check.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/probes/rpc_capture.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/probes/shared_link_probe.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/api/__init__.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/api/accountApi.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/api/activityApi.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/api/assetApi.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/api/baseApi.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/api/frameApi.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/api/notificationApi.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/api/peopleApi.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/api/playlistApi.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/aura.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/aws/__init__.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/aws/awsclient.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/aws/s3client.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/aws/sqsclient.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/cache.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/client.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/exif.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/export.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/google/__init__.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/google/cache.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/google/client.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/google/enumerate.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/google/manifest.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/google/parsers.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/google/redaction.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/google/vault.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/gsync.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/migration.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/models/__init__.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/models/activity.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/models/asset.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/models/frame.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/models/meta.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/models/person.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/models/user.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/ratelimit.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/reconcile.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/sync.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/utils/dt.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/utils/io.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/pushframe/utils/settings.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/scripts/build-deb.sh +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/scripts/make-apt-key.sh +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/scripts/publish-apt-repo.sh +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/scripts/test-apt-journey-container.sh +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/scripts/test-deb-container.sh +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/scripts/test-install-journey-container.sh +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/conftest.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/fixtures/asset_unprocessed.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/fixtures/assets_page1.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/fixtures/assets_page2.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/fixtures/assets_placeholders.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/fixtures/error_envelope.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/fixtures/frame_detail.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/fixtures/frames.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/fixtures/google_rpc_snackc_page.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/fixtures/google_share_page_sample.html +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/fixtures/login.json +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/fixtures/probe_af_initdata_sample.html +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/offline.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_asset_partial.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_asset_unprocessed.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_aura_logger.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_batch_update_contract.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_cli_apply.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_cli_google_album.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_cli_inspect.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_cli_push_budget_geo.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_cli_reconcile.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_cli_status.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_cli_status_google.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_cli_sync.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_client_rate_limit.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_execute_plan.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_execute_plan_budget_geo.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_fixtures_validity.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_google_cache.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_google_client.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_google_enumerate.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_google_manifest.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_google_parsers.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_google_vault.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_gsync_engine.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_gsync_execute.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_imports.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_migration.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_offline_read_path.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_prep_upload_formats.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_probe_browser.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_probe_shared_link.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_ratelimit.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_read_path.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_reconcile.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_retry_401.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_settings_budget.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_sync_engine.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_write_endpoints_failloud.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_write_formats_live.py +0 -0
- {pushframe-5.0.2 → pushframe-5.0.4}/tests/test_write_throttling.py +0 -0
|
@@ -36,7 +36,7 @@ jobs:
|
|
|
36
36
|
outputs:
|
|
37
37
|
version: ${{ steps.version.outputs.version }}
|
|
38
38
|
steps:
|
|
39
|
-
- uses: actions/checkout@
|
|
39
|
+
- uses: actions/checkout@v7
|
|
40
40
|
- name: Assert tag == pyproject == pushframe.__version__
|
|
41
41
|
id: version
|
|
42
42
|
run: |
|
|
@@ -56,8 +56,8 @@ jobs:
|
|
|
56
56
|
runs-on: ubuntu-latest
|
|
57
57
|
environment: release
|
|
58
58
|
steps:
|
|
59
|
-
- uses: actions/checkout@
|
|
60
|
-
- uses: astral-sh/setup-uv@
|
|
59
|
+
- uses: actions/checkout@v7
|
|
60
|
+
- uses: astral-sh/setup-uv@v10.2.0
|
|
61
61
|
with:
|
|
62
62
|
enable-cache: true
|
|
63
63
|
- name: Build sdist + wheel
|
|
@@ -70,8 +70,8 @@ jobs:
|
|
|
70
70
|
needs: check
|
|
71
71
|
runs-on: ubuntu-latest
|
|
72
72
|
steps:
|
|
73
|
-
- uses: actions/checkout@
|
|
74
|
-
- uses: astral-sh/setup-uv@
|
|
73
|
+
- uses: actions/checkout@v7
|
|
74
|
+
- uses: astral-sh/setup-uv@v10.2.0
|
|
75
75
|
with:
|
|
76
76
|
enable-cache: true
|
|
77
77
|
- name: Install uv-managed standalone python (the deb's runtime)
|
|
@@ -94,8 +94,8 @@ jobs:
|
|
|
94
94
|
runs-on: ubuntu-latest
|
|
95
95
|
environment: release
|
|
96
96
|
steps:
|
|
97
|
-
- uses: actions/checkout@
|
|
98
|
-
- uses: astral-sh/setup-uv@
|
|
97
|
+
- uses: actions/checkout@v7
|
|
98
|
+
- uses: astral-sh/setup-uv@v10.2.0
|
|
99
99
|
- name: Restore the APT signing key from the secret
|
|
100
100
|
env:
|
|
101
101
|
PUSHFRAME_APT_SIGNING_KEY: ${{ secrets.PUSHFRAME_APT_SIGNING_KEY }}
|
|
@@ -126,8 +126,8 @@ jobs:
|
|
|
126
126
|
runs-on: ubuntu-latest
|
|
127
127
|
environment: release
|
|
128
128
|
steps:
|
|
129
|
-
- uses: actions/checkout@
|
|
130
|
-
- uses: astral-sh/setup-uv@
|
|
129
|
+
- uses: actions/checkout@v7
|
|
130
|
+
- uses: astral-sh/setup-uv@v10.2.0
|
|
131
131
|
with:
|
|
132
132
|
enable-cache: true
|
|
133
133
|
- name: Build sdist + wheel
|
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Milestones
|
|
2
2
|
|
|
3
|
+
## v5.0 — Distribution & Rename: pushframe packages (Shipped: 2026-09-29)
|
|
4
|
+
|
|
5
|
+
**Phases completed:** 3 phases (20-22), 4 plans — the first milestone
|
|
6
|
+
about *shipping the tool itself* rather than its features.
|
|
7
|
+
|
|
8
|
+
**Key accomplishments:**
|
|
9
|
+
|
|
10
|
+
| Phase | Delivered | Proof |
|
|
11
|
+
|-------|-----------|-------|
|
|
12
|
+
| 20 — Rename & repo switch | `auraframes`→`pushframe` (module, binary, config migration), env `PUSHFRAME_*` primary, standalone repo `coredmp95/pushframe` (not a fork), MIT LICENSE + provenance | 407 tests green through the rename; live migration validated; name cleared on PyPI + trademark-adjacency checked |
|
|
13
|
+
| 21 — Debian + APT | Hermetic `.deb` (embedded CPython 3.14, lintian 0E/0W, clean removal), signed APT repo live on GitHub Pages, container journeys for both channels | bytecode-ownership defect caught by our own container test and fixed for every user; live-URL journey exit 0 |
|
|
14
|
+
| 22 — PyPI + releases | Trusted publishing (OIDC, zero PyPI tokens), tag-triggered release workflow, `--version` single-sourced, OPERATOR-STEPS + CHANGELOG | v5.0.2 run all-green 5/5 jobs; v5.0.3 carries the Changelog URL |
|
|
15
|
+
|
|
16
|
+
**Shipped releases:** 5.0.0 → 5.0.1 (page metadata) → 5.0.2 (first
|
|
17
|
+
pipeline-complete) → 5.0.3 (changelog URL) — each on PyPI + TestPyPI +
|
|
18
|
+
APT + GitHub Releases simultaneously. First real deployment:
|
|
19
|
+
venus.coredmp.net via the signed APT repo (human-driven: keyring →
|
|
20
|
+
sources → install).
|
|
21
|
+
|
|
22
|
+
**Known gaps carried forward:** 5.0.0 remains on PyPI (empty page,
|
|
23
|
+
immutable) — yank candidate; `AURA_*` env vars in a one-release
|
|
24
|
+
deprecation window; credentials still live in env vars/.env (v5.1's
|
|
25
|
+
charter: config wizard + token-first sessions).
|
|
26
|
+
|
|
27
|
+
|
|
3
28
|
## v4.0 Local Google Photos Album Sync (Shipped: 2026-09-29)
|
|
4
29
|
|
|
5
30
|
**Phases completed:** 4 phases (16-19), 10 plans, offline suite 349 → **401 tests**
|
|
@@ -364,3 +364,5 @@ sequences write-path reliability first, then Google account linking → album di
|
|
|
364
364
|
album-to-frame mirroring via a pruned local cache, then the carried debt. Biggest open
|
|
365
365
|
unknown: whether Google's post-March-2025 Photos API still permits enumerating a user's own
|
|
366
366
|
albums, or whether album selection has to go through the Picker API.*
|
|
367
|
+
|
|
368
|
+
**Current Milestone:** v5.1 — Operations: Config, Sessions, Multi-frame & Scheduling (started 2026-09-29)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Requirements: pushframe — v5.1 Operations: Config, Sessions, Multi-frame & Scheduling
|
|
2
|
+
|
|
3
|
+
**Defined:** 2026-09-29
|
|
4
|
+
**Core Value:** `pushframe` becomes *operable unattended*: configuration is a
|
|
5
|
+
conversation (`pushframe config`) instead of env-var archaeology, the Aura
|
|
6
|
+
password never touches disk (token-first sessions), mirrors run on a schedule
|
|
7
|
+
without root (systemd user timers), one album can mirror to every frame
|
|
8
|
+
(named mappings), and every command that needs a machine prerequisite fails
|
|
9
|
+
with the remedy instead of a traceback.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
### Config wizard (CFG)
|
|
14
|
+
|
|
15
|
+
- [ ] **CFG-01**: `pushframe config` (interactive) asks for and stores: Aura
|
|
16
|
+
email, Aura secret, default frame name, and the tool's non-secret settings
|
|
17
|
+
(default album, write-budget override, debug) — prompts are masked for
|
|
18
|
+
secrets (getpass-style), values are validated (email shape; login test on
|
|
19
|
+
request), and the result is written to `~/.config/pushframe/config.json`
|
|
20
|
+
with mode `0600`. Re-running edits in place (existing values shown
|
|
21
|
+
redacted, Enter keeps).
|
|
22
|
+
- [ ] **CFG-02**: precedence is `env var > config file > built-in default`
|
|
23
|
+
everywhere the CLI reads configuration; the env vars keep working exactly
|
|
24
|
+
as today (deprecation window opened in 5.0.0 stays honored); `pushframe
|
|
25
|
+
config show` prints the *effective* configuration with secrets redacted
|
|
26
|
+
and the source of each value (env/file/default).
|
|
27
|
+
- [ ] **CFG-03**: `pushframe config import` migrates an existing `.env`
|
|
28
|
+
(or exported `PUSHFRAME_*`/`AURA_*` set) into `config.json` without
|
|
29
|
+
retyping; the command reports what it took from where and never stores
|
|
30
|
+
what it could resolve from the environment instead.
|
|
31
|
+
- [ ] **CFG-04**: `pushframe config path` prints the config file location;
|
|
32
|
+
`pushframe config set <key> <value>` / `get <key>` exist for scripts;
|
|
33
|
+
unknown keys fail with the list of known keys.
|
|
34
|
+
|
|
35
|
+
### Credential handling (SEC — token-first)
|
|
36
|
+
|
|
37
|
+
- [ ] **SEC-01**: the Aura password is **never persisted** — not in
|
|
38
|
+
`config.json`, not in env files the tool writes. `pushframe config`
|
|
39
|
+
authenticates once, stores the returned `auth_token` (0600) plus the
|
|
40
|
+
account email, and discards the password when the process exits.
|
|
41
|
+
- [ ] **SEC-02**: every command that needs the API uses the stored token
|
|
42
|
+
(header auth) and falls back to interactive password login **only** when
|
|
43
|
+
the token is absent/expired/revoked, after which the new token is
|
|
44
|
+
persisted; a `--password` / `PUSHFRAME_PASSWORD` override still wins
|
|
45
|
+
(CI/script path) but is documented as discouraged for humans.
|
|
46
|
+
- [ ] **SEC-03**: `pushframe logout` deletes the stored token (and only the
|
|
47
|
+
token); token material never appears in logs, output, or the history
|
|
48
|
+
ledger (existing redaction stays enforced by tests).
|
|
49
|
+
|
|
50
|
+
### Scheduling (TMR — systemd user)
|
|
51
|
+
|
|
52
|
+
- [ ] **TMR-01**: `pushframe schedule add <job>` installs a systemd **user**
|
|
53
|
+
timer + service unit under `~/.config/systemd/user/` for the supported
|
|
54
|
+
jobs (`google-sync --apply` for a named pair, directory `sync`) with a
|
|
55
|
+
prompted or `--every` schedule; no root anywhere; `pushframe schedule
|
|
56
|
+
list` shows installed jobs with next-run times (from `systemctl list-timers`).
|
|
57
|
+
- [ ] **TMR-02**: `pushframe schedule remove <job>` uninstalls cleanly
|
|
58
|
+
(units + timer state); installed units are named `pushframe-<job>.service/.timer`
|
|
59
|
+
and never collide with system units.
|
|
60
|
+
- [ ] **TMR-03**: unattended correctness: a scheduled run uses only
|
|
61
|
+
stored configuration (no prompts), honors SAFE-02's removal threshold
|
|
62
|
+
(a run that would exceed it **skips and logs** rather than fails the unit),
|
|
63
|
+
writes a per-job log (`~/.local/state/pushframe/<job>.log`), and the
|
|
64
|
+
docs cover `loginctl enable-linger` for headless machines (venus).
|
|
65
|
+
|
|
66
|
+
### Multi-frame (MTF — GSF-01 closed)
|
|
67
|
+
|
|
68
|
+
- [ ] **MTF-01**: named **album↔frame mappings** live in config: one album
|
|
69
|
+
may mirror to N frames and one frame may receive from N albums
|
|
70
|
+
(`pushframe config` manages them; `--pair <name>` selects one,
|
|
71
|
+
`--all` selects every pair).
|
|
72
|
+
- [ ] **MTF-02**: `google-sync` resolves a pair the same way it resolves the
|
|
73
|
+
current single pair today (dry-run default, `--apply` gated, SAFE-01..04
|
|
74
|
+
per pair); **state is per-pair** — the manifest and staging cache are
|
|
75
|
+
sharded by pair so two pairs never share dedupe memory.
|
|
76
|
+
- [ ] **MTF-03**: the write budget is **account-wide and shared** across
|
|
77
|
+
pairs within one run (`--all`), preserving SAFE-02 semantics at account
|
|
78
|
+
level; per-pair reports stay exact (pairs list what they did, and a
|
|
79
|
+
skipped pair never blocks the others).
|
|
80
|
+
|
|
81
|
+
### Preflights & error quality (PRF)
|
|
82
|
+
|
|
83
|
+
- [ ] **PRF-01**: commands with machine prerequisites check them up front
|
|
84
|
+
and fail with per-item remedies — `google-link` (playwright package,
|
|
85
|
+
Chrome/Chromium, profile dir) ships in 5.1's first cut (already
|
|
86
|
+
implemented on master), extended to: `google-sync` (vault present),
|
|
87
|
+
`schedule` (systemd user session available, `loginctl` linger status),
|
|
88
|
+
and `sync`/`push` (target dir exists/contains images).
|
|
89
|
+
- [ ] **PRF-02**: no user-facing command may end in an unhandled traceback
|
|
90
|
+
for a foreseeable condition (missing module, missing browser, missing
|
|
91
|
+
vault, ambiguous frame, multi-arch notice): each maps to a named,
|
|
92
|
+
one-screen error with the next action. A test sweep asserts the
|
|
93
|
+
traceback-free contract for the documented failure modes.
|
|
94
|
+
|
|
95
|
+
## Non-Goals
|
|
96
|
+
|
|
97
|
+
| Feature | Reason |
|
|
98
|
+
|---------|--------|
|
|
99
|
+
| OS keyring storage (gnome-keyring/Secret Service) | headless servers (venus) lack a keyring session; file-0600 token is the contract, keyring is a later nicety |
|
|
100
|
+
| Encrypting config.json with a user passphrase | circularity (where does the passphrase live?); token-first removes the high-value secret anyway |
|
|
101
|
+
| Cron support | systemd user timers are the modern path; cron adds a second code path for no new capability |
|
|
102
|
+
| Real deletion exposure on the Google verb | unchanged posture from v2.0/v4.0; hide-not-delete stays |
|
|
103
|
+
| Many-to-many with per-pair schedules | each pair is its own scheduled job — same capability, simpler model |
|
|
104
|
+
|
|
105
|
+
## Traceability
|
|
106
|
+
|
|
107
|
+
Every v5.1 requirement maps to exactly one phase; numbering continues from
|
|
108
|
+
Phase 22.
|
|
109
|
+
|
|
110
|
+
| Requirement | Phase | Status |
|
|
111
|
+
|-------------|-------|--------|
|
|
112
|
+
| CFG-01..04 | Phase 23 | Pending |
|
|
113
|
+
| SEC-01..03 | Phase 24 | Pending |
|
|
114
|
+
| PRF-01..02 | Phase 24 | Pending |
|
|
115
|
+
| MTF-01..03 | Phase 25 | Pending |
|
|
116
|
+
| TMR-01..03 | Phase 25 | Pending |
|
|
117
|
+
|
|
118
|
+
**Coverage:** v5.1 requirements: 14 total — no orphans, no double-mapping.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# pushframe Roadmap — v5.1 Operations: Config, Sessions, Multi-frame & Scheduling
|
|
2
|
+
|
|
3
|
+
**Defined:** 2026-09-29
|
|
4
|
+
**Ships when:** a fresh machine goes from `apt install pushframe` to a
|
|
5
|
+
scheduled, unattended, multi-frame Google mirror with **zero** hand-edited
|
|
6
|
+
config files and **zero** stored passwords.
|
|
7
|
+
|
|
8
|
+
## Milestone Goal
|
|
9
|
+
|
|
10
|
+
Make pushframe *operable* the way it is *installable*: one conversational
|
|
11
|
+
command (`pushframe config`) to set everything up, password-free sessions
|
|
12
|
+
(token-first), `pushframe schedule` for root-less systemd user timers,
|
|
13
|
+
named album↔frame mappings with per-pair mirror state, and preflights that
|
|
14
|
+
always fail with a remedy.
|
|
15
|
+
|
|
16
|
+
## Phases
|
|
17
|
+
|
|
18
|
+
### Phase 23: Config Wizard & Precedence (CFG-01..04)
|
|
19
|
+
|
|
20
|
+
**Goal**: `pushframe config` replaces env-var archaeology — interactive,
|
|
21
|
+
masked, validated, `0600`; env vars keep working; `show` prints effective
|
|
22
|
+
config with sources; `import` swallows an existing `.env`.
|
|
23
|
+
|
|
24
|
+
**Success Criteria**:
|
|
25
|
+
|
|
26
|
+
1. On a fresh machine, `pushframe config` → `pushframe status` works with
|
|
27
|
+
no env vars set at all (file-only path), verified in a clean container.
|
|
28
|
+
2. With env vars set, they override the file — proven by a test that flips
|
|
29
|
+
both and asserts which value each command sees.
|
|
30
|
+
3. `config show` never prints a secret value (redaction test); `config
|
|
31
|
+
import` on a real `.env` reproduces the same effective config as the
|
|
32
|
+
env-var path (golden diff test).
|
|
33
|
+
|
|
34
|
+
**Depends on**: nothing (master already carries the google-link preflights
|
|
35
|
+
that started this work).
|
|
36
|
+
|
|
37
|
+
### Phase 24: Token-First Sessions & Preflight Sweep (SEC-01..03, PRF-01..02)
|
|
38
|
+
|
|
39
|
+
**Goal**: the password is used once at login and never stored; the token
|
|
40
|
+
drives every subsequent command with transparent re-login on expiry; the
|
|
41
|
+
preflight pattern from google-link covers every command's machine
|
|
42
|
+
prerequisites; no foreseeable condition ends in a traceback.
|
|
43
|
+
|
|
44
|
+
**Success Criteria**:
|
|
45
|
+
|
|
46
|
+
1. `pushframe config` + login → `~/.config/pushframe/` contains a token,
|
|
47
|
+
no password, mode 0600 (file-content test).
|
|
48
|
+
2. A token-expiry simulation (mocked 401) transparently re-logins once and
|
|
49
|
+
retries the request; a second consecutive failure surfaces the login
|
|
50
|
+
error (no loops).
|
|
51
|
+
3. The traceback-free sweep passes: every documented foreseeable failure
|
|
52
|
+
mode maps to a named error with a remedy (parametrized test).
|
|
53
|
+
|
|
54
|
+
**Depends on**: Phase 23 (config file is where the token lives).
|
|
55
|
+
|
|
56
|
+
### Phase 25: Multi-frame Mappings & systemd User Scheduling (MTF-01..03, TMR-01..03)
|
|
57
|
+
|
|
58
|
+
**Goal**: GSF-01 and GSF-02 close — named album↔frame pairs (N:M),
|
|
59
|
+
per-pair mirror state with an account-wide shared write budget, and
|
|
60
|
+
`pushframe schedule` installing systemd **user** timers that run pairs
|
|
61
|
+
unattended (SAFE-02 skips-and-logs, per-job logs, linger documented for
|
|
62
|
+
headless hosts like venus).
|
|
63
|
+
|
|
64
|
+
**Success Criteria**:
|
|
65
|
+
|
|
66
|
+
1. Two pairs (one album → two frames) sync in one `--all` run, each with
|
|
67
|
+
its own manifest/cache shard, the shared budget capping the total, and
|
|
68
|
+
per-pair reports exact (container + fake-API proof).
|
|
69
|
+
2. `schedule add/list/remove` round-trips units in
|
|
70
|
+
`~/.config/systemd/user/` (unit-content assertions in a container with
|
|
71
|
+
systemd available); a scheduled google-sync run is prompt-free and
|
|
72
|
+
logs to `~/.local/state/pushframe/<job>.log`.
|
|
73
|
+
3. SAFE-02 behavior under scheduling: a pair whose plan exceeds the
|
|
74
|
+
removal threshold is skipped-and-logged, the unit exits 0, and the
|
|
75
|
+
other pairs still run.
|
|
76
|
+
|
|
77
|
+
**Depends on**: Phase 24 (scheduled runs read token sessions, not
|
|
78
|
+
passwords; preflights guard scheduled contexts).
|
|
79
|
+
|
|
80
|
+
## Progress
|
|
81
|
+
|
|
82
|
+
**Execution Order:** 23 → 24 → 25
|
|
83
|
+
|
|
84
|
+
| Phase | Plans Complete | Status | Completed |
|
|
85
|
+
|-------|----------------|--------|-----------|
|
|
86
|
+
| 23. Config Wizard & Precedence | 0/? | Not started | - |
|
|
87
|
+
| 24. Token-First Sessions & Preflight Sweep | 0/? | Not started | - |
|
|
88
|
+
| 25. Multi-frame & systemd User Scheduling | 0/? | Not started | - |
|
|
89
|
+
|
|
90
|
+
## Requirement Coverage (v5.1)
|
|
91
|
+
|
|
92
|
+
| Phase | Requirements | Count |
|
|
93
|
+
|-------|--------------|-------|
|
|
94
|
+
| 23 | CFG-01..04 | 4 |
|
|
95
|
+
| 24 | SEC-01..03, PRF-01..02 | 5 |
|
|
96
|
+
| 25 | MTF-01..03, TMR-01..03 | 6 |
|
|
97
|
+
| **Total** | | **15 / 15** |
|
|
98
|
+
|
|
99
|
+
No orphaned requirements; no requirement mapped to more than one phase.
|
|
100
|
+
|
|
101
|
+
## Backlog
|
|
102
|
+
|
|
103
|
+
- Yank 5.0.0 from PyPI (empty-page release, superseded by 5.0.3).
|
|
104
|
+
- OS keyring token storage (Secret Service) as an optional backend.
|
|
105
|
+
- Ubuntu 26 runner observation after 2026-10-19 (deb job toolchain).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# pushframe — State
|
|
2
|
+
|
|
3
|
+
**Milestone:** v5.1 — Operations: Config, Sessions, Multi-frame & Scheduling
|
|
4
|
+
**Started:** 2026-09-29
|
|
5
|
+
|
|
6
|
+
## Current Position
|
|
7
|
+
|
|
8
|
+
Phase: 23 — Config Wizard & Precedence
|
|
9
|
+
Current Plan: Not started
|
|
10
|
+
Total Plans in Phase: 0
|
|
11
|
+
Status: Ready to plan
|
|
12
|
+
|
|
13
|
+
## Milestone Roadmap (v5.1, Phases 23-25)
|
|
14
|
+
|
|
15
|
+
- [ ] Phase 23 — Config Wizard & Precedence (CFG-01..04)
|
|
16
|
+
- [ ] Phase 24 — Token-First Sessions & Preflight Sweep (SEC-01..03, PRF-01..02)
|
|
17
|
+
- [ ] Phase 25 — Multi-frame Mappings & systemd User Scheduling (MTF-01..03, TMR-01..03)
|
|
18
|
+
|
|
19
|
+
## Completed Milestones
|
|
20
|
+
|
|
21
|
+
- v4.0 — Local Google Photos Album Sync (2026-09-29)
|
|
22
|
+
- v5.0 — Distribution & Rename: pushframe packages (2026-09-29)
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
# Requirements Archive: v5.0 v5.0
|
|
2
|
+
|
|
3
|
+
**Archived:** 2026-09-29
|
|
4
|
+
**Status:** SHIPPED
|
|
5
|
+
|
|
6
|
+
For current requirements, see `.planning/REQUIREMENTS.md`.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
1
10
|
# Requirements: Aura Frames Python Client — v5.0 Distribution & Rename: pushframe packages
|
|
2
11
|
|
|
3
12
|
**Defined:** 2026-09-29
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contract": "1.0.0",
|
|
3
|
+
"flavor": "core",
|
|
4
|
+
"milestone": {
|
|
5
|
+
"version": "v5.1",
|
|
6
|
+
"name": "Operations: Config, Sessions, Multi-frame & Scheduling",
|
|
7
|
+
"started": "2026-09-29"
|
|
8
|
+
},
|
|
9
|
+
"phases": [
|
|
10
|
+
{
|
|
11
|
+
"number": "23",
|
|
12
|
+
"name": "Config Wizard & Precedence",
|
|
13
|
+
"status": "pending"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"number": "24",
|
|
17
|
+
"name": "Token-First Sessions & Preflight Sweep",
|
|
18
|
+
"status": "pending"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"number": "25",
|
|
22
|
+
"name": "Multi-frame & systemd User Scheduling",
|
|
23
|
+
"status": "pending"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"next": {
|
|
27
|
+
"command": "/gsd:progress --next",
|
|
28
|
+
"label": "Advance to the next step",
|
|
29
|
+
"reason": "Phase 23 of 3 \u00b7 0% \u00b7 ready to plan"
|
|
30
|
+
},
|
|
31
|
+
"updated_at": "2026-09-29T13:27:41.229Z"
|
|
32
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `pushframe` are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
Each release ships simultaneously to [PyPI](https://pypi.org/project/pushframe/),
|
|
8
|
+
the [signed APT repository](https://coredmp95.github.io/pushframe/), and
|
|
9
|
+
[GitHub Releases](https://github.com/coredmp95/pushframe/releases) — one tag,
|
|
10
|
+
every channel.
|
|
11
|
+
|
|
12
|
+
`pushframe` is an unofficial community CLI for Aura Frames digital photo
|
|
13
|
+
frames; it is not affiliated with Aura Frames Inc.
|
|
14
|
+
|
|
15
|
+
## [5.0.2] — 2026-09-29
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **PyPI project page** — 5.0.0/5.0.1 shipped no package description: the
|
|
20
|
+
wheel metadata now carries the README (`readme`), a one-line summary with
|
|
21
|
+
the not-affiliated disclaimer, and Homepage/Repository/Issues URLs.
|
|
22
|
+
- **Release pipeline, APT job** (CI-only, no code change vs 5.0.1): the
|
|
23
|
+
signing-key fingerprint is derived with gpg instead of a grep over the
|
|
24
|
+
ASCII armor, and the gh-pages orphan commit runs with an explicit git
|
|
25
|
+
identity — first release where all five jobs (check, pypi-test, deb,
|
|
26
|
+
apt, pypi) are green end-to-end.
|
|
27
|
+
- **CI actions** — `actions/checkout@v7`, `astral-sh/setup-uv@v10.2.0`
|
|
28
|
+
(Node 24): clears the Node.js 20 deprecation warnings on the runners.
|
|
29
|
+
|
|
30
|
+
## [5.0.1] — 2026-09-29
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- Wheel/sdist metadata: `readme = README.md`, `description`, and
|
|
35
|
+
`project.urls` declared (the 5.0.0 PyPI page rendered empty; versions
|
|
36
|
+
being immutable on PyPI, the fix ships as a new release).
|
|
37
|
+
|
|
38
|
+
## [5.0.0] — 2026-09-29
|
|
39
|
+
|
|
40
|
+
The first distribution release — and the first version published outside
|
|
41
|
+
git tags. Aligns with the v5.0 milestone (« Distribution & Rename »).
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- **Debian packaging** (`scripts/build-deb.sh`): hermetic `.deb` embedding
|
|
46
|
+
its own CPython 3.14 under `/usr/lib/pushframe/` — no system Python is
|
|
47
|
+
used or modified; lintian-clean (0 errors, 0 warnings); removal leaves
|
|
48
|
+
no residue (bytecode is package-owned, `PYTHONDONTWRITEBYTECODE` at run
|
|
49
|
+
time); verified in clean `ubuntu:26.04` containers.
|
|
50
|
+
- **Signed APT repository** at `https://coredmp95.github.io/pushframe/`
|
|
51
|
+
(dedicated no-passphrase GPG key, InRelease/Release.gpg, keyring +
|
|
52
|
+
one-line sources entry), plus container tests proving the full user
|
|
53
|
+
journey: `apt update` signature-clean → `apt install pushframe` →
|
|
54
|
+
working CLI.
|
|
55
|
+
- **PyPI distribution** via GitHub Actions **trusted publishing** (OIDC)
|
|
56
|
+
— no PyPI token exists anywhere; TestPyPI rehearsal gates every real
|
|
57
|
+
upload.
|
|
58
|
+
- **Release automation** (`release.yml`): pushing a `v*` tag builds the
|
|
59
|
+
wheel/sdist, the `.deb` (attached to the GitHub Release), republishes
|
|
60
|
+
the APT repository, and uploads to PyPI — with a version-consistency
|
|
61
|
+
gate (tag == pyproject == `pushframe.__version__`).
|
|
62
|
+
- **Install journeys as tests**: clean-container proofs for all three
|
|
63
|
+
channels (`.deb` file, APT, `uv tool install`).
|
|
64
|
+
- `pushframe --version` prints `pushframe <release>` (single-sourced,
|
|
65
|
+
lockstep-guarded by tests and the release gate).
|
|
66
|
+
|
|
67
|
+
### Changed
|
|
68
|
+
|
|
69
|
+
- Project renamed **auraframes → pushframe** (module, binary, config):
|
|
70
|
+
the old name collided with an existing PyPI package and is
|
|
71
|
+
trademark-adjacent; config migrates automatically
|
|
72
|
+
(`~/.config/auraframes/` → `~/.config/pushframe/`, non-destructive).
|
|
73
|
+
- Environment variables: `PUSHFRAME_*` is primary; `AURA_*` still read
|
|
74
|
+
for one release as a deprecation window.
|
|
75
|
+
|
|
76
|
+
### Deprecated
|
|
77
|
+
|
|
78
|
+
- `AURA_*` environment variables (read until 5.x; set `PUSHFRAME_*`).
|
|
79
|
+
- `aura-cli` as an installed command: removed in favor of the single
|
|
80
|
+
`pushframe` binary.
|
|
81
|
+
|
|
82
|
+
### Security
|
|
83
|
+
|
|
84
|
+
- Repository moved to a standalone repo (not a fork); MIT LICENSE with
|
|
85
|
+
provenance; GitHub security features enabled (secret scanning + push
|
|
86
|
+
protection, Dependabot, CodeQL).
|
|
87
|
+
|
|
88
|
+
## Pre-distribution history (git tags only, never published to a package index)
|
|
89
|
+
|
|
90
|
+
Milestone summary — see `.planning/MILESTONES.md` for the full retros.
|
|
91
|
+
|
|
92
|
+
- **v4.0 — Local Google Photos Album Sync** (phases 16–19, 2026-09):
|
|
93
|
+
`google-link` (dedicated Chrome profile, cookie vault `0600`),
|
|
94
|
+
`google-album` (full walk, exact byte counts), `google-sync`
|
|
95
|
+
(hide-by-default mirror semantics, pruned cache + persistent manifest,
|
|
96
|
+
SAFE-01..04 guards); live UAT two-run proof (upload run → zero-upload
|
|
97
|
+
steady state); debt closeout (AWS config out of code, single logger
|
|
98
|
+
per process, transport seam).
|
|
99
|
+
- **v3.0 — direct transport rewrite**: `Client` over `httpx` (HTTP/2),
|
|
100
|
+
boto3 S3/SQS upload path, offline test harness (mocket), full offline
|
|
101
|
+
suite; the server-side relay approach was abandoned this milestone.
|
|
102
|
+
- **v2.0 — read path hardening**: `status`/`inspect`/`sync`/`push`
|
|
103
|
+
verbs, asset lifecycle states, anti-abuse paced writes, staged
|
|
104
|
+
uploads with cleanup on failure.
|
|
105
|
+
- **v1.1 — client transport fixes** (the original author's last tag;
|
|
106
|
+
revived and extended by the current maintainer in 2026).
|
|
107
|
+
- **v1.0 — initial upstream release** by zmanowar (2023).
|
|
108
|
+
|
|
109
|
+
## [Unreleased]
|
|
110
|
+
|
|
111
|
+
- (v5.1 work will land here)
|
|
112
|
+
|
|
113
|
+
## [5.0.4] — 2026-09-29
|
|
114
|
+
|
|
115
|
+
### Fixed
|
|
116
|
+
|
|
117
|
+
- google-link preflight on the uv-tool install path: remedy for a missing
|
|
118
|
+
playwright now matches every install shape (`uv tool install
|
|
119
|
+
'pushframe[google-browser]' --force` for uv tools — `pip install
|
|
120
|
+
--user` targets the wrong interpreter there); stray duplicate quote in
|
|
121
|
+
the message fixed.
|
|
122
|
+
|
|
123
|
+
### Added
|
|
124
|
+
|
|
125
|
+
- google-link zero-config: dedicated Chrome profile defaults to
|
|
126
|
+
`~/.config/pushframe/chrome-profile` (created on demand); the env var
|
|
127
|
+
becomes an override. A near-miss env name (e.g. a truncated
|
|
128
|
+
`USHFRAME_…`) is called out explicitly instead of looking like "unset".
|
|
129
|
+
- google-link preflight: missing prerequisites (playwright package,
|
|
130
|
+
Chrome/Chromium) fail with the exact remedy instead of a traceback
|
|
131
|
+
(`ModuleNotFoundError: playwright` was the whole output before).
|
|
132
|
+
|
|
133
|
+
### Changed
|
|
134
|
+
|
|
135
|
+
- `PUSHFRAME_PROBE_CHROME_PROFILE` is no longer required to run
|
|
136
|
+
`google-link`.
|
|
137
|
+
|
|
138
|
+
- google-link zero-config: the dedicated Chrome profile defaults to
|
|
139
|
+
`~/.config/pushframe/chrome-profile` (created on demand); the env var
|
|
140
|
+
becomes an override. A near-miss env name (e.g. a truncated
|
|
141
|
+
`USHFRAME_…`) is called out explicitly instead of looking like "unset".
|
|
142
|
+
- google-link preflight: missing prerequisites (playwright package,
|
|
143
|
+
Chrome/Chromium) now fail with the exact remedy instead of a traceback
|
|
144
|
+
(`ModuleNotFoundError: playwright` was the whole output before).
|
|
145
|
+
|
|
146
|
+
### Fixed
|
|
147
|
+
|
|
148
|
+
- `google-link` preflight on the uv-tool install path: the message for a
|
|
149
|
+
missing playwright package now matches every install shape (`uv tool
|
|
150
|
+
install 'pushframe[google-browser]'` for uv tools — `pip install
|
|
151
|
+
--user` targets the wrong interpreter there), and the leftover
|
|
152
|
+
duplicate browser-detection line was removed.
|
|
153
|
+
|
|
154
|
+
### Changed
|
|
155
|
+
|
|
156
|
+
- `PUSHFRAME_PROBE_CHROME_PROFILE` is no longer required to run
|
|
157
|
+
`google-link`.
|
|
158
|
+
|
|
159
|
+
## [5.0.3] — 2026-09-29
|
|
160
|
+
|
|
161
|
+
### Added
|
|
162
|
+
|
|
163
|
+
- `CHANGELOG.md` — every release now traced in Keep a Changelog format
|
|
164
|
+
(Added / Changed / Deprecated / Fixed / Security), exposed as a
|
|
165
|
+
`Changelog` project URL on PyPI and referenced from the README.
|
|
166
|
+
- `arch=amd64` in the documented APT sources entry: silences apt's
|
|
167
|
+
i386 notice on multi-arch machines (the repo is amd64-only).
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pushframe
|
|
3
|
-
Version: 5.0.
|
|
3
|
+
Version: 5.0.4
|
|
4
4
|
Summary: Unofficial community CLI for Aura Frames digital photo frames (sync a local folder or a Google Photos album; not affiliated with Aura Frames Inc.)
|
|
5
5
|
Project-URL: Homepage, https://github.com/coredmp95/pushframe
|
|
6
6
|
Project-URL: Repository, https://github.com/coredmp95/pushframe
|
|
7
7
|
Project-URL: Issues, https://github.com/coredmp95/pushframe/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/coredmp95/pushframe/blob/master/CHANGELOG.md
|
|
8
9
|
License: MIT License
|
|
9
10
|
|
|
10
11
|
Copyright (c) 2026 Fabrice DIDIERJEAN (coredmp95)
|
|
@@ -91,6 +92,9 @@ Any advice or issues are welcome.
|
|
|
91
92
|
environment, dependency, and interpreter management.
|
|
92
93
|
- A live Aura account (email + password) for any command that actually hits the API.
|
|
93
94
|
|
|
95
|
+
Release history lives in [CHANGELOG.md](CHANGELOG.md) (Added / Changed /
|
|
96
|
+
Deprecated / Fixed / Security per release, Keep a Changelog format).
|
|
97
|
+
|
|
94
98
|
## Install (Ubuntu/Debian)
|
|
95
99
|
|
|
96
100
|
Pre-built `.deb` packages embed their own Python 3.14 runtime under
|
|
@@ -135,8 +139,9 @@ sudo install -d -m 0755 /etc/apt/keyrings
|
|
|
135
139
|
curl -fsSL https://coredmp95.github.io/pushframe/dists/pushframe.asc \
|
|
136
140
|
| sudo gpg --dearmor -o /etc/apt/keyrings/pushframe.gpg
|
|
137
141
|
|
|
138
|
-
# 2. add the sources entry
|
|
139
|
-
|
|
142
|
+
# 2. add the sources entry (arch=amd64: the repo is amd64-only — on
|
|
143
|
+
# multi-arch machines this silences apt's i386 notice)
|
|
144
|
+
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/pushframe.gpg] https://coredmp95.github.io/pushframe stable main" \
|
|
140
145
|
| sudo tee /etc/apt/sources.list.d/pushframe.list
|
|
141
146
|
|
|
142
147
|
# 3. install
|
|
@@ -32,6 +32,9 @@ Any advice or issues are welcome.
|
|
|
32
32
|
environment, dependency, and interpreter management.
|
|
33
33
|
- A live Aura account (email + password) for any command that actually hits the API.
|
|
34
34
|
|
|
35
|
+
Release history lives in [CHANGELOG.md](CHANGELOG.md) (Added / Changed /
|
|
36
|
+
Deprecated / Fixed / Security per release, Keep a Changelog format).
|
|
37
|
+
|
|
35
38
|
## Install (Ubuntu/Debian)
|
|
36
39
|
|
|
37
40
|
Pre-built `.deb` packages embed their own Python 3.14 runtime under
|
|
@@ -76,8 +79,9 @@ sudo install -d -m 0755 /etc/apt/keyrings
|
|
|
76
79
|
curl -fsSL https://coredmp95.github.io/pushframe/dists/pushframe.asc \
|
|
77
80
|
| sudo gpg --dearmor -o /etc/apt/keyrings/pushframe.gpg
|
|
78
81
|
|
|
79
|
-
# 2. add the sources entry
|
|
80
|
-
|
|
82
|
+
# 2. add the sources entry (arch=amd64: the repo is amd64-only — on
|
|
83
|
+
# multi-arch machines this silences apt's i386 notice)
|
|
84
|
+
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/pushframe.gpg] https://coredmp95.github.io/pushframe stable main" \
|
|
81
85
|
| sudo tee /etc/apt/sources.list.d/pushframe.list
|
|
82
86
|
|
|
83
87
|
# 3. install
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
# pushframe — unofficial community CLI for Aura Frames (not affiliated).
|
|
2
2
|
# Version single source for the CLI surface (REL-02); pyproject keeps the
|
|
3
3
|
# packaging metadata version and tests/test_version.py enforces lockstep.
|
|
4
|
-
__version__ = "5.0.
|
|
4
|
+
__version__ = "5.0.4"
|
|
@@ -324,12 +324,10 @@ def run_google_link(*, debug: bool = False, bootstrap_fn=None) -> int:
|
|
|
324
324
|
"""
|
|
325
325
|
_configure_cli_logging(debug)
|
|
326
326
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
f'chrome-profile) and re-run (T-16-06)')
|
|
332
|
-
return 1
|
|
327
|
+
# v5.1: no env prerequisite here — bootstrap._require_profile() owns the
|
|
328
|
+
# precedence (override > legacy > built-in default, created on demand)
|
|
329
|
+
# and raises a helpful BootstrapError (near-miss names included) that the
|
|
330
|
+
# handler below prints verbatim.
|
|
333
331
|
|
|
334
332
|
# Re-link notice (LGS-02): same command refreshes an existing session.
|
|
335
333
|
# Vault read routes through from_vault (denylist-sanctioned); a dead or
|