altero 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. altero-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +47 -0
  2. altero-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  3. altero-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +16 -0
  4. altero-0.1.0/.github/dependabot.yml +17 -0
  5. altero-0.1.0/.github/workflows/ci.yml +117 -0
  6. altero-0.1.0/.github/workflows/publish.yml +29 -0
  7. altero-0.1.0/.gitignore +24 -0
  8. altero-0.1.0/.python-version +1 -0
  9. altero-0.1.0/.vscode/launch.json +60 -0
  10. altero-0.1.0/ARCHITECTURE.md +668 -0
  11. altero-0.1.0/CHANGELOG.md +28 -0
  12. altero-0.1.0/LICENSE +22 -0
  13. altero-0.1.0/PKG-INFO +166 -0
  14. altero-0.1.0/README.md +135 -0
  15. altero-0.1.0/RELEASING.md +143 -0
  16. altero-0.1.0/SECURITY.md +25 -0
  17. altero-0.1.0/TESTING.md +496 -0
  18. altero-0.1.0/assets/tui-watch.png +0 -0
  19. altero-0.1.0/packaging/altero-engine.spec +77 -0
  20. altero-0.1.0/packaging/build-app +350 -0
  21. altero-0.1.0/packaging/engine_entry.py +5 -0
  22. altero-0.1.0/packaging/install-app +87 -0
  23. altero-0.1.0/pyproject.toml +71 -0
  24. altero-0.1.0/src/altero/__init__.py +9 -0
  25. altero-0.1.0/src/altero/__main__.py +6 -0
  26. altero-0.1.0/src/altero/appearance.py +219 -0
  27. altero-0.1.0/src/altero/assets/menubar-template.png +0 -0
  28. altero-0.1.0/src/altero/assets/menubar-template@2x.png +0 -0
  29. altero-0.1.0/src/altero/autoswitch.py +2859 -0
  30. altero-0.1.0/src/altero/bundle.py +120 -0
  31. altero-0.1.0/src/altero/cache.py +44 -0
  32. altero-0.1.0/src/altero/claude_locks.py +187 -0
  33. altero-0.1.0/src/altero/cli.py +1989 -0
  34. altero-0.1.0/src/altero/credentials.py +1849 -0
  35. altero-0.1.0/src/altero/exceptions.py +91 -0
  36. altero-0.1.0/src/altero/fsutil.py +101 -0
  37. altero-0.1.0/src/altero/json_output.py +289 -0
  38. altero-0.1.0/src/altero/launch_agent.py +923 -0
  39. altero-0.1.0/src/altero/locking.py +269 -0
  40. altero-0.1.0/src/altero/logging_config.py +64 -0
  41. altero-0.1.0/src/altero/macos_keychain.py +226 -0
  42. altero-0.1.0/src/altero/mappings.py +142 -0
  43. altero-0.1.0/src/altero/menubar.py +1288 -0
  44. altero-0.1.0/src/altero/migrations.py +537 -0
  45. altero-0.1.0/src/altero/models.py +211 -0
  46. altero-0.1.0/src/altero/oauth.py +806 -0
  47. altero-0.1.0/src/altero/pace.py +196 -0
  48. altero-0.1.0/src/altero/paths.py +110 -0
  49. altero-0.1.0/src/altero/poll_policy.py +270 -0
  50. altero-0.1.0/src/altero/printer.py +232 -0
  51. altero-0.1.0/src/altero/process_detection.py +350 -0
  52. altero-0.1.0/src/altero/session.py +1499 -0
  53. altero-0.1.0/src/altero/settings.py +527 -0
  54. altero-0.1.0/src/altero/snapshot_json.py +295 -0
  55. altero-0.1.0/src/altero/snapshot_source.py +100 -0
  56. altero-0.1.0/src/altero/state_watch.py +110 -0
  57. altero-0.1.0/src/altero/switcher.py +7449 -0
  58. altero-0.1.0/src/altero/transfer.py +645 -0
  59. altero-0.1.0/src/altero/tui/__init__.py +66 -0
  60. altero-0.1.0/src/altero/tui/altero.tcss +205 -0
  61. altero-0.1.0/src/altero/tui/app.py +467 -0
  62. altero-0.1.0/src/altero/tui/autoview.py +454 -0
  63. altero-0.1.0/src/altero/tui/dashboard.py +432 -0
  64. altero-0.1.0/src/altero/tui/data.py +194 -0
  65. altero-0.1.0/src/altero/tui/modals.py +159 -0
  66. altero-0.1.0/src/altero/tui/theme.py +141 -0
  67. altero-0.1.0/src/altero/tui/widgets.py +403 -0
  68. altero-0.1.0/src/altero/update_check.py +215 -0
  69. altero-0.1.0/src/altero/usage_history.py +145 -0
  70. altero-0.1.0/src/altero/usage_store.py +1234 -0
  71. altero-0.1.0/src/altero/widget_requests.py +217 -0
  72. altero-0.1.0/tests/__init__.py +1 -0
  73. altero-0.1.0/tests/conftest.py +892 -0
  74. altero-0.1.0/tests/fixtures/sample_config.json +10 -0
  75. altero-0.1.0/tests/fixtures/snapshot_golden.json +166 -0
  76. altero-0.1.0/tests/test_add_account_identity.py +720 -0
  77. altero-0.1.0/tests/test_api_key_accounts.py +1108 -0
  78. altero-0.1.0/tests/test_appearance.py +331 -0
  79. altero-0.1.0/tests/test_autoswitch.py +7636 -0
  80. altero-0.1.0/tests/test_bundle.py +336 -0
  81. altero-0.1.0/tests/test_cache.py +72 -0
  82. altero-0.1.0/tests/test_claude_locks.py +199 -0
  83. altero-0.1.0/tests/test_cli.py +2155 -0
  84. altero-0.1.0/tests/test_colour_cache_isolation.py +196 -0
  85. altero-0.1.0/tests/test_config_cli.py +272 -0
  86. altero-0.1.0/tests/test_credentials.py +273 -0
  87. altero-0.1.0/tests/test_fsutil.py +286 -0
  88. altero-0.1.0/tests/test_json_output.py +755 -0
  89. altero-0.1.0/tests/test_launch_agent.py +1213 -0
  90. altero-0.1.0/tests/test_locking.py +280 -0
  91. altero-0.1.0/tests/test_logging_config.py +58 -0
  92. altero-0.1.0/tests/test_macos_keychain.py +212 -0
  93. altero-0.1.0/tests/test_macos_keychain_contract.py +1202 -0
  94. altero-0.1.0/tests/test_mappings.py +185 -0
  95. altero-0.1.0/tests/test_menubar.py +764 -0
  96. altero-0.1.0/tests/test_migrations.py +596 -0
  97. altero-0.1.0/tests/test_move_accounts.py +578 -0
  98. altero-0.1.0/tests/test_oauth.py +1524 -0
  99. altero-0.1.0/tests/test_pace.py +191 -0
  100. altero-0.1.0/tests/test_paths.py +150 -0
  101. altero-0.1.0/tests/test_poll_policy.py +315 -0
  102. altero-0.1.0/tests/test_printer.py +308 -0
  103. altero-0.1.0/tests/test_process_detection.py +650 -0
  104. altero-0.1.0/tests/test_real_store_guard.py +844 -0
  105. altero-0.1.0/tests/test_session.py +2862 -0
  106. altero-0.1.0/tests/test_settings.py +397 -0
  107. altero-0.1.0/tests/test_snapshot_json.py +792 -0
  108. altero-0.1.0/tests/test_state_watch.py +178 -0
  109. altero-0.1.0/tests/test_swap_accounts.py +542 -0
  110. altero-0.1.0/tests/test_switcher.py +12408 -0
  111. altero-0.1.0/tests/test_theme.py +67 -0
  112. altero-0.1.0/tests/test_transfer.py +2024 -0
  113. altero-0.1.0/tests/test_tui.py +1958 -0
  114. altero-0.1.0/tests/test_update_check.py +364 -0
  115. altero-0.1.0/tests/test_usage_history.py +84 -0
  116. altero-0.1.0/tests/test_usage_store.py +1698 -0
  117. altero-0.1.0/tests/test_widget_requests.py +283 -0
  118. altero-0.1.0/uv.lock +361 -0
  119. altero-0.1.0/widget/.swiftlint.yml +7 -0
  120. altero-0.1.0/widget/App/AlteroWidgetHost.entitlements +17 -0
  121. altero-0.1.0/widget/App/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
  122. altero-0.1.0/widget/App/Assets.xcassets/AppIcon.appiconset/icon_1024.png +0 -0
  123. altero-0.1.0/widget/App/Assets.xcassets/AppIcon.appiconset/icon_128.png +0 -0
  124. altero-0.1.0/widget/App/Assets.xcassets/AppIcon.appiconset/icon_16.png +0 -0
  125. altero-0.1.0/widget/App/Assets.xcassets/AppIcon.appiconset/icon_256.png +0 -0
  126. altero-0.1.0/widget/App/Assets.xcassets/AppIcon.appiconset/icon_32.png +0 -0
  127. altero-0.1.0/widget/App/Assets.xcassets/AppIcon.appiconset/icon_512.png +0 -0
  128. altero-0.1.0/widget/App/Assets.xcassets/AppIcon.appiconset/icon_64.png +0 -0
  129. altero-0.1.0/widget/App/Assets.xcassets/Contents.json +6 -0
  130. altero-0.1.0/widget/App/HostMain.swift +323 -0
  131. altero-0.1.0/widget/README.md +618 -0
  132. altero-0.1.0/widget/Shared/AccountSwitch.swift +119 -0
  133. altero-0.1.0/widget/Shared/AutoswitchToggle.swift +117 -0
  134. altero-0.1.0/widget/Shared/BackendStart.swift +191 -0
  135. altero-0.1.0/widget/Shared/CompactAction.swift +37 -0
  136. altero-0.1.0/widget/Shared/Display.swift +380 -0
  137. altero-0.1.0/widget/Shared/Navigation.swift +124 -0
  138. altero-0.1.0/widget/Shared/RequestDrop.swift +37 -0
  139. altero-0.1.0/widget/Shared/Snapshot.swift +173 -0
  140. altero-0.1.0/widget/Shared/Trend.swift +94 -0
  141. altero-0.1.0/widget/Signing.xcconfig.example +9 -0
  142. altero-0.1.0/widget/Tests/AccountSwitchTests.swift +132 -0
  143. altero-0.1.0/widget/Tests/AutoswitchFixtureTests.swift +70 -0
  144. altero-0.1.0/widget/Tests/AutoswitchToggleTests.swift +128 -0
  145. altero-0.1.0/widget/Tests/BackendStartTests.swift +200 -0
  146. altero-0.1.0/widget/Tests/CompactActionTests.swift +76 -0
  147. altero-0.1.0/widget/Tests/DisplayTests.swift +382 -0
  148. altero-0.1.0/widget/Tests/Fixtures/snapshot_autoswitch.json +93 -0
  149. altero-0.1.0/widget/Tests/ResetTargetTests.swift +48 -0
  150. altero-0.1.0/widget/Tests/SessionPaceTests.swift +33 -0
  151. altero-0.1.0/widget/Tests/SnapshotGoldenTests.swift +242 -0
  152. altero-0.1.0/widget/Tests/WeeklyOutlookTests.swift +67 -0
  153. altero-0.1.0/widget/Widget/ActionControls.swift +212 -0
  154. altero-0.1.0/widget/Widget/AlteroWidget.swift +120 -0
  155. altero-0.1.0/widget/Widget/AlteroWidgetBundle.swift +9 -0
  156. altero-0.1.0/widget/Widget/AlteroWidgetExtension.entitlements +36 -0
  157. altero-0.1.0/widget/Widget/AutoStatusLine.swift +231 -0
  158. altero-0.1.0/widget/Widget/Components.swift +400 -0
  159. altero-0.1.0/widget/Widget/DetailPages.swift +67 -0
  160. altero-0.1.0/widget/Widget/ExtraLargePage.swift +307 -0
  161. altero-0.1.0/widget/Widget/Intents.swift +325 -0
  162. altero-0.1.0/widget/Widget/LargePages.swift +276 -0
  163. altero-0.1.0/widget/Widget/MediumPage.swift +183 -0
  164. altero-0.1.0/widget/Widget/PaceLine.swift +148 -0
  165. altero-0.1.0/widget/Widget/Pages.swift +275 -0
  166. altero-0.1.0/widget/Widget/Palette.swift +22 -0
  167. altero-0.1.0/widget/Widget/SnapshotFile.swift +56 -0
  168. altero-0.1.0/widget/build-widget +135 -0
  169. altero-0.1.0/widget/make-app-icon.swift +259 -0
  170. altero-0.1.0/widget/make-menubar-icon.swift +147 -0
  171. altero-0.1.0/widget/project.yml +157 -0
@@ -0,0 +1,47 @@
1
+ name: Bug report
2
+ description: Something in Altero isn't working right
3
+ labels: [bug]
4
+ body:
5
+ - type: textarea
6
+ id: what-happened
7
+ attributes:
8
+ label: What happened?
9
+ description: What did you do, what did you see, and what did you expect instead?
10
+ placeholder: Ran `altero switch 2`, got ... — expected ...
11
+ validations:
12
+ required: true
13
+ - type: input
14
+ id: version
15
+ attributes:
16
+ label: Altero version and install method
17
+ description: Output of `altero --version`, and whether you installed with uv, pipx, or from source.
18
+ placeholder: altero 0.1.0, installed with uv
19
+ validations:
20
+ required: true
21
+ - type: dropdown
22
+ id: os
23
+ attributes:
24
+ label: Operating system
25
+ description: Credentials are stored differently per platform, so this matters a lot.
26
+ options:
27
+ - macOS
28
+ - Linux
29
+ - Windows
30
+ - WSL
31
+ validations:
32
+ required: true
33
+ - type: dropdown
34
+ id: claude-code
35
+ attributes:
36
+ label: How do you run Claude Code?
37
+ multiple: true
38
+ options:
39
+ - CLI (terminal)
40
+ - VS Code extension
41
+ - Desktop app
42
+ - type: textarea
43
+ id: logs
44
+ attributes:
45
+ label: Command output or logs
46
+ description: Paste the failing command's output — `altero list` for account-state issues, `altero auto` log lines for auto-switch issues. Formatted automatically, no backticks needed. Please redact emails/account identifiers, and never paste access/refresh tokens, API keys, setup tokens, or credential-file/Keychain contents.
47
+ render: shell
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: Report a security vulnerability
4
+ url: https://github.com/FullContextLabs/Altero/security/advisories/new
5
+ about: Please report vulnerabilities privately, not as a public issue. See SECURITY.md.
@@ -0,0 +1,16 @@
1
+ name: Feature request
2
+ description: Suggest an improvement or new capability
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: What problem would this solve?
9
+ description: Describe the situation where you miss this feature — the workflow matters more than the mechanism.
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: solution
14
+ attributes:
15
+ label: What would you like to happen?
16
+ description: A rough sketch is fine — commands, flags, behavior.
@@ -0,0 +1,17 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ groups:
8
+ github-actions:
9
+ patterns: ["*"]
10
+
11
+ - package-ecosystem: "uv"
12
+ directory: "/"
13
+ schedule:
14
+ interval: "weekly"
15
+ groups:
16
+ python-dependencies:
17
+ patterns: ["*"]
@@ -0,0 +1,117 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ test:
18
+ name: test (${{ matrix.os }}, py${{ matrix.python-version }})
19
+ runs-on: ${{ matrix.os }}
20
+ # macOS: a `security` call can block on an invisible SecurityAgent
21
+ # dialog; faulthandler below dumps every thread's stack past its budget,
22
+ # and this is the backstop if even that hangs.
23
+ timeout-minutes: ${{ matrix.os == 'macos-latest' && 15 || 10 }}
24
+ strategy:
25
+ fail-fast: false
26
+ matrix:
27
+ os: [ubuntu-latest, windows-latest, macos-latest]
28
+ # Matches [project] requires-python (">=3.12") and the classifiers
29
+ # in pyproject.toml (3.12, 3.13, 3.14).
30
+ python-version: ['3.12', '3.13', '3.14']
31
+
32
+ steps:
33
+ - uses: actions/checkout@v7
34
+
35
+ # uv (not pip) so the PEP 735 dev dependency-group -- pytest,
36
+ # pytest-asyncio, pytest-xdist -- installs from the committed
37
+ # lockfile, same as local development.
38
+ - name: Install uv
39
+ uses: astral-sh/setup-uv@v7
40
+ with:
41
+ python-version: ${{ matrix.python-version }}
42
+ enable-cache: true
43
+
44
+ # menubar (rumps) carries its own `sys_platform == 'darwin'` marker,
45
+ # so the extra resolves to nothing on Linux/Windows -- but only macOS
46
+ # needs it installed.
47
+ - name: Install dependencies (macOS)
48
+ if: runner.os == 'macOS'
49
+ run: uv sync --locked --extra menubar
50
+
51
+ - name: Install dependencies
52
+ if: runner.os != 'macOS'
53
+ run: uv sync --locked
54
+
55
+ # faulthandler_timeout is set everywhere the whole suite runs on
56
+ # macOS, matching the previous macos-keychain job: it caught a hung
57
+ # `security` call that the default timeout alone would only kill
58
+ # silently.
59
+ - name: Run tests
60
+ run: uv run pytest -q ${{ runner.os == 'macOS' && '-o faulthandler_timeout=600' || '' }}
61
+
62
+ build-sanity:
63
+ name: build sanity (sdist + wheel)
64
+ runs-on: ubuntu-latest
65
+ timeout-minutes: 10
66
+ steps:
67
+ - uses: actions/checkout@v7
68
+
69
+ - name: Install uv
70
+ uses: astral-sh/setup-uv@v7
71
+ with:
72
+ python-version: '3.12'
73
+ enable-cache: true
74
+
75
+ - name: Build sdist and wheel
76
+ run: uv build
77
+
78
+ - name: Check distributions with twine
79
+ run: uv run --with twine twine check dist/*
80
+
81
+ widget:
82
+ name: widget (build, test, lint)
83
+ runs-on: macos-latest
84
+ timeout-minutes: 20
85
+ steps:
86
+ - uses: actions/checkout@v7
87
+
88
+ - name: Install xcodegen
89
+ run: brew install xcodegen
90
+
91
+ - name: Install swiftlint
92
+ run: brew install swiftlint
93
+
94
+ # Signing.xcconfig is gitignored (per-developer Team ID). The example's
95
+ # blank DEVELOPMENT_TEAM is fine: the build below is unsigned.
96
+ - name: Set up Signing.xcconfig
97
+ working-directory: widget
98
+ run: cp Signing.xcconfig.example Signing.xcconfig
99
+
100
+ - name: Generate Xcode project
101
+ working-directory: widget
102
+ run: xcodegen generate
103
+
104
+ # Unsigned: CI has no Apple Developer Team ID / certificate. The
105
+ # golden fixture (tests/fixtures/snapshot_golden.json) is bundled as a
106
+ # test resource straight from its repo path by project.yml, so the
107
+ # checkout alone is enough for it to resolve.
108
+ - name: Build and test (unsigned)
109
+ working-directory: widget
110
+ run: |
111
+ xcodebuild -project AlteroWidget.xcodeproj -scheme AlteroWidgetTests \
112
+ -destination 'platform=macOS' \
113
+ CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO test
114
+
115
+ - name: SwiftLint
116
+ working-directory: widget
117
+ run: swiftlint
@@ -0,0 +1,29 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ environment: pypi
11
+ permissions:
12
+ id-token: write
13
+
14
+ steps:
15
+ - uses: actions/checkout@v7
16
+
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v7
19
+ with:
20
+ python-version: '3.12'
21
+
22
+ - name: Install build dependencies
23
+ run: pip install build
24
+
25
+ - name: Build package
26
+ run: python -m build
27
+
28
+ - name: Publish to PyPI
29
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,24 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # superpowers session planning artifacts (not part of the project)
13
+ docs/superpowers/
14
+
15
+ # Xcode (widget/). The .xcodeproj and both Info.plists are generated by
16
+ # XcodeGen; Signing.xcconfig holds the per-developer Team ID. `build/` above
17
+ # already covers build directories.
18
+ widget/*.xcodeproj/
19
+ widget/Signing.xcconfig
20
+ widget/App/Info.plist
21
+ widget/Widget/Info.plist
22
+ DerivedData/
23
+ xcuserdata/
24
+ *.xcuserstate
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1,60 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "altero --list",
6
+ "type": "debugpy",
7
+ "request": "launch",
8
+ "module": "altero.cli",
9
+ "args": ["--list"],
10
+ "cwd": "${workspaceFolder}",
11
+ "env": {
12
+ "PYTHONPATH": "${workspaceFolder}/src"
13
+ },
14
+ "console": "integratedTerminal"
15
+ },
16
+ {
17
+ "name": "altero --switch",
18
+ "type": "debugpy",
19
+ "request": "launch",
20
+ "module": "altero.cli",
21
+ "args": ["--switch"],
22
+ "cwd": "${workspaceFolder}",
23
+ "env": {
24
+ "PYTHONPATH": "${workspaceFolder}/src"
25
+ },
26
+ "console": "integratedTerminal"
27
+ },
28
+ {
29
+ "name": "altero --purge",
30
+ "type": "debugpy",
31
+ "request": "launch",
32
+ "module": "altero.cli",
33
+ "args": ["--purge"],
34
+ "cwd": "${workspaceFolder}",
35
+ "env": {
36
+ "PYTHONPATH": "${workspaceFolder}/src"
37
+ },
38
+ "console": "integratedTerminal"
39
+ },
40
+ {
41
+ "name": "altero (custom args)",
42
+ "type": "debugpy",
43
+ "request": "launch",
44
+ "module": "altero.cli",
45
+ "args": ["${input:cliArgs}"],
46
+ "cwd": "${workspaceFolder}",
47
+ "env": {
48
+ "PYTHONPATH": "${workspaceFolder}/src"
49
+ },
50
+ "console": "integratedTerminal"
51
+ }
52
+ ],
53
+ "inputs": [
54
+ {
55
+ "id": "cliArgs",
56
+ "type": "promptString",
57
+ "description": "CLI arguments (e.g., --list, --status, --switch)"
58
+ }
59
+ ]
60
+ }