agr-opentui 0.2.2__tar.gz → 0.3.2__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 (109) hide show
  1. agr_opentui-0.3.2/.github/CODEOWNERS +5 -0
  2. agr_opentui-0.3.2/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  3. agr_opentui-0.3.2/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/.github/workflows/build-bin.yml +1 -1
  5. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/.github/workflows/bump-version.yml +1 -1
  6. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/Makefile +1 -1
  7. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/PKG-INFO +55 -70
  8. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/README.md +53 -68
  9. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/pyproject.toml +2 -2
  10. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/app.ts +1 -0
  11. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/app_logic.ts +9 -7
  12. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_actions.ts +2 -1
  13. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/ui/controller.ts +11 -3
  14. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/app_logic.test.ts +25 -1
  15. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_actions_service.test.ts +1 -0
  16. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/runtime_handlers.test.ts +11 -0
  17. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/ui_controller.test.ts +1 -1
  18. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/uv.lock +2 -2
  19. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/.github/renovate.json5 +0 -0
  20. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/.github/workflows/ci.yml +0 -0
  21. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/.github/workflows/publish-pypi.yml +0 -0
  22. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/.gitignore +0 -0
  23. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/agr_opentui/__init__.py +0 -0
  24. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/agr_opentui/bridge.py +0 -0
  25. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/bun.lock +0 -0
  26. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/bunfig.toml +0 -0
  27. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/package.json +0 -0
  28. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/skills.json +0 -0
  29. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/commands.ts +0 -0
  30. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/deps.ts +0 -0
  31. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/main.ts +0 -0
  32. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/runtime/doctor.ts +0 -0
  33. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/runtime/handlers.ts +0 -0
  34. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/runtime/modal_input_handler.ts +0 -0
  35. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/add_flow.ts +0 -0
  36. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/agr.ts +0 -0
  37. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/agr_actions.ts +0 -0
  38. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/clipboard.ts +0 -0
  39. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/data.ts +0 -0
  40. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/discover_filter.ts +0 -0
  41. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/discover_labels.ts +0 -0
  42. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/feedback.ts +0 -0
  43. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/handle_match.ts +0 -0
  44. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/input_mode.ts +0 -0
  45. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/navigation.ts +0 -0
  46. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/preview.ts +0 -0
  47. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_all.ts +0 -0
  48. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_details.ts +0 -0
  49. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_footer.ts +0 -0
  50. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_help.ts +0 -0
  51. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_list.ts +0 -0
  52. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_missing_config.ts +0 -0
  53. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_preview.ts +0 -0
  54. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_run_modal.ts +0 -0
  55. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_run_options.ts +0 -0
  56. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_tabs.ts +0 -0
  57. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_update_confirm.ts +0 -0
  58. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/render_verify.ts +0 -0
  59. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/runtime_ops.ts +0 -0
  60. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/selection.ts +0 -0
  61. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/skills_file.ts +0 -0
  62. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/skills_source.ts +0 -0
  63. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/ui_feedback.ts +0 -0
  64. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/update.ts +0 -0
  65. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/verify.ts +0 -0
  66. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/verify_coordinator.ts +0 -0
  67. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/services/visible_items.ts +0 -0
  68. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/state.ts +0 -0
  69. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/ui/layout.ts +0 -0
  70. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/ui/render.ts +0 -0
  71. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/ui/rows_render.ts +0 -0
  72. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/src/ui.ts +0 -0
  73. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/add_flow_service.test.ts +0 -0
  74. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/agr_actions.test.ts +0 -0
  75. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/agr_service.test.ts +0 -0
  76. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/clipboard_service.test.ts +0 -0
  77. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/commands_service.test.ts +0 -0
  78. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/data_service.test.ts +0 -0
  79. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/discover_filter_service.test.ts +0 -0
  80. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/discover_labels.test.ts +0 -0
  81. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/feedback_service.test.ts +0 -0
  82. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/handle_match_service.test.ts +0 -0
  83. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/input_mode_service.test.ts +0 -0
  84. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/navigation_service.test.ts +0 -0
  85. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/preview_service.test.ts +0 -0
  86. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_all_service.test.ts +0 -0
  87. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_details_service.test.ts +0 -0
  88. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_footer_service.test.ts +0 -0
  89. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_help_service.test.ts +0 -0
  90. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_list_service.test.ts +0 -0
  91. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_missing_config_service.test.ts +0 -0
  92. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_preview_service.test.ts +0 -0
  93. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_run_modal_service.test.ts +0 -0
  94. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_run_options_service.test.ts +0 -0
  95. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_tabs_service.test.ts +0 -0
  96. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_update_confirm_service.test.ts +0 -0
  97. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/render_verify_service.test.ts +0 -0
  98. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/rows_render.test.ts +0 -0
  99. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/runtime_doctor.test.ts +0 -0
  100. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/runtime_ops_service.test.ts +0 -0
  101. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/selection_service.test.ts +0 -0
  102. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/skills_file_service.test.ts +0 -0
  103. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/skills_source.test.ts +0 -0
  104. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/ui_feedback_adapter.test.ts +0 -0
  105. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/update_service.test.ts +0 -0
  106. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/verify_coordinator_service.test.ts +0 -0
  107. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/verify_service.test.ts +0 -0
  108. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/test/visible_items_service.test.ts +0 -0
  109. {agr_opentui-0.2.2 → agr_opentui-0.3.2}/tsconfig.json +0 -0
@@ -0,0 +1,5 @@
1
+ # These owners will be the default owners for everything in
2
+ # the repo. Unless a later match takes precedence,
3
+ # @global-owner1 and @global-owner2 will be requested for
4
+ # review when someone opens a pull request.
5
+ * @RelativeSure
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior:
15
+ 1. Go to '...'
16
+ 2. Click on '....'
17
+ 3. Scroll down to '....'
18
+ 4. See error
19
+
20
+ **Expected behavior**
21
+ A clear and concise description of what you expected to happen.
22
+
23
+ **Screenshots**
24
+ If applicable, add screenshots to help explain your problem.
25
+
26
+ **Desktop (please complete the following information):**
27
+ - OS: [e.g. iOS]
28
+ - Browser [e.g. chrome, safari]
29
+ - Version [e.g. 22]
30
+
31
+ **Smartphone (please complete the following information):**
32
+ - Device: [e.g. iPhone6]
33
+ - OS: [e.g. iOS8.1]
34
+ - Browser [e.g. stock browser, safari]
35
+ - Version [e.g. 22]
36
+
37
+ **Additional context**
38
+ Add any other context about the problem here.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Is your feature request related to a problem? Please describe.**
11
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
+
13
+ **Describe the solution you'd like**
14
+ A clear and concise description of what you want to happen.
15
+
16
+ **Describe alternatives you've considered**
17
+ A clear and concise description of any alternative solutions or features you've considered.
18
+
19
+ **Additional context**
20
+ Add any other context or screenshots about the feature request here.
@@ -60,7 +60,7 @@ jobs:
60
60
  echo "name=${name}" >> "$GITHUB_OUTPUT"
61
61
 
62
62
  - name: Rename binary
63
- run: mv bin/agr-tui "bin/${{ steps.name.outputs.name }}"
63
+ run: mv bin/agr-opentui "bin/${{ steps.name.outputs.name }}"
64
64
 
65
65
  - name: Upload artifact
66
66
  uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
@@ -61,7 +61,7 @@ jobs:
61
61
  python-version: "3.14.3"
62
62
 
63
63
  - name: Setup uv
64
- uses: astral-sh/setup-uv@v6
64
+ uses: astral-sh/setup-uv@v7
65
65
 
66
66
  - name: Validate and apply version bump
67
67
  env:
@@ -2,7 +2,7 @@ BUN ?= bun
2
2
  PYTHON ?= python3
3
3
  ENTRY ?= src/main.ts
4
4
  OUT_DIR ?= bin
5
- OUT ?= $(OUT_DIR)/agr-tui
5
+ OUT ?= $(OUT_DIR)/agr-opentui
6
6
  DIST_DIR ?= dist
7
7
 
8
8
  .PHONY: build clean
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agr-opentui
3
- Version: 0.2.2
3
+ Version: 0.3.2
4
4
  Summary: OpenTUI frontend for agr
5
5
  Project-URL: Homepage, https://github.com/RelativeSure/agr-opentui
6
6
  Project-URL: Repository, https://github.com/RelativeSure/agr-opentui
@@ -17,13 +17,45 @@ Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Programming Language :: Python :: 3.14
18
18
  Classifier: Topic :: Software Development :: Build Tools
19
19
  Classifier: Topic :: Utilities
20
- Requires-Python: >=3.14
20
+ Requires-Python: >=3.14.3
21
21
  Requires-Dist: agr>=0.7.4
22
22
  Description-Content-Type: text/markdown
23
23
 
24
- # OpenTUI for agr
24
+ <div align="center">
25
25
 
26
- OpenTUI front-end for managing `agr` skills: browse `agr.toml`, install/remove skills, preview `SKILL.md`, and run skills via `agrx`. Skill discovery is based on `https://github.com/kasperjunge/agent-resources`.
26
+ # OpenTUI for `agr` and `agrx`
27
+
28
+ An OpenTUI interface for the `agr`/`agrx` CLI: view configured skills, trigger `agr` actions and preview `SKILL.md`
29
+
30
+ [![PyPI](https://img.shields.io/pypi/v/agr-opentui?color=blue)](https://pypi.org/project/agr-opentui/)
31
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
32
+
33
+ </div>
34
+
35
+ ---
36
+
37
+ `agr-opentui` is an OpenTUI front-end for `agr`/`agrx`.
38
+ The default discover source in this repo points to `https://github.com/kasperjunge/agent-resources`.
39
+
40
+ ## Install from PyPI
41
+
42
+ With `uv`:
43
+
44
+ ```bash
45
+ uv tool install agr-opentui
46
+ ```
47
+
48
+ With `pip`:
49
+
50
+ ```bash
51
+ python -m pip install agr-opentui
52
+ ```
53
+
54
+ Then run:
55
+
56
+ ```bash
57
+ agr-opentui
58
+ ```
27
59
 
28
60
  ## Usage
29
61
 
@@ -83,98 +115,50 @@ Discover flow:
83
115
 
84
116
  ## Requirements
85
117
 
86
- Runtime (using `agr-tui`):
118
+ ### Runtime (using `agr-opentui`):
87
119
  - Python 3.10+
88
120
  - `uv`
89
121
  - `agr` + `agrx` on your `PATH`
90
122
 
91
- Build/Development (working on this repo):
123
+ ### Build/Development (working on this repo):
92
124
  - Bun 1.3.8+
93
125
  - Zig (required by OpenTUI build tooling)
94
126
 
95
- ## Install
96
-
97
- ```bash
98
- bun install
99
- ```
100
-
101
- ## Run
102
-
103
- ```bash
104
- bun run src/main.ts
105
- ```
106
-
107
- Run it from the repo you want to manage (the current working directory is the target repo).
108
- `agr.toml` is expected in that target repo for `agr add/remove/sync` operations.
109
-
110
- ### Run From Target Repo
111
-
112
- ```bash
113
- cd /path/to/your/project
114
- agr-tui
115
- ```
116
-
117
- `agr-opentui` itself does not need to contain your target repo's `agr.toml`.
118
-
119
- ## Build
127
+ #### Build
120
128
 
121
129
  ```bash
122
130
  bun run build
123
131
  ```
124
-
125
- This creates `bin/agr-tui`.
126
-
127
- ## Publish to PyPI
128
-
129
- One-time setup:
130
- - Create a `pypi` environment in this GitHub repo.
131
- - In your PyPI project settings, add this repo/workflow as a Trusted Publisher for `.github/workflows/publish-pypi.yml`.
132
- - Optional: add `testpypi` environment and TestPyPI Trusted Publisher too.
133
-
134
- Publish via GitHub Actions:
135
- - Release publish: creating a GitHub release triggers publish to PyPI.
136
- - Manual: run `publish-pypi` workflow and choose `pypi` or `testpypi`.
137
-
138
- Publish from local machine:
139
-
132
+ or
140
133
  ```bash
141
- python -m pip install --upgrade build twine
142
- make py-publish # Upload to PyPI
143
- make py-publish-test # Upload to TestPyPI
134
+ make build
144
135
  ```
136
+ This creates `bin/agr-opentui`.
145
137
 
146
- ## Bump Version
147
138
 
148
- Update package version before creating a release:
149
-
150
- 1. Edit `pyproject.toml` and bump `[project].version`.
151
- 2. Regenerate `uv.lock` so the local package entry matches:
139
+ #### Install
152
140
 
153
141
  ```bash
154
- uv lock
142
+ bun install
155
143
  ```
156
144
 
157
- 3. Run checks:
145
+ #### Run
158
146
 
159
147
  ```bash
160
- make check
148
+ bun run src/main.ts
161
149
  ```
162
150
 
163
- 4. Commit the version bump:
151
+ Run it from the repo you want to manage (the current working directory is the target repo).
152
+ `agr.toml` is expected in that target repo for `agr add/remove/sync` operations.
153
+
154
+ ### Run From Target Repo
164
155
 
165
156
  ```bash
166
- git add pyproject.toml uv.lock
167
- git commit -m "chore: bump version to X.Y.Z"
157
+ cd /path/to/your/project
158
+ agr-opentui
168
159
  ```
169
160
 
170
- 5. Create a GitHub release for `vX.Y.Z` (or manually run `publish-pypi` workflow).
171
-
172
- `publish-pypi.yml` runs automatically when a release is published.
173
-
174
- Alternative: use `.github/workflows/bump-version.yml` via **Actions → bump-version → Run workflow** and provide:
175
- - `version` (required): target version like `0.3.0`
176
- - `branch` (required): target branch to update (default `master`)
177
- - `create_tag` (required, default enabled): creates/pushes tag `v<version>` and creates a GitHub Release
161
+ `agr-opentui` itself does not need to contain your target repo's `agr.toml`.
178
162
 
179
163
  ## Discover List (`skills.json`)
180
164
 
@@ -183,6 +167,8 @@ If `skills.json` exists, the `Discover` tab will list its entries. It supports:
183
167
  - An array of strings or objects (`{ "label": "...", "handle": "...", "repo": "owner/repo" }`).
184
168
  - An object with `source` metadata and `skills` array (see `skills.json` in this repo).
185
169
 
170
+ In this repository, `skills.json` is configured to source skills from `kasperjunge/agent-resources` (`agr.toml` on `main`).
171
+
186
172
  When a `source` is configured, the app checks the remote list periodically (about every 6 hours) and can update `skills.json` using the `u`/`U`/`s`/`S` controls.
187
173
 
188
174
  ## Troubleshooting
@@ -194,7 +180,6 @@ When a `source` is configured, the app checks the remote list periodically (abou
194
180
  - `skills.json not found` or parse errors: fix the file format (array or `{ "source": ..., "skills": [...] }`).
195
181
  - Discover list not updating: check the `source` URL/repo/branch/path and network access.
196
182
  - `SKILL.md` preview says “not found”: the skill may not ship a `SKILL.md` or the path is nonstandard.
197
- - Copy to clipboard doesn’t work: install `pbcopy` (macOS), `wl-copy` (Wayland), or `xclip` (X11).
198
183
 
199
184
  ## Notes
200
185
 
@@ -1,6 +1,38 @@
1
- # OpenTUI for agr
1
+ <div align="center">
2
2
 
3
- OpenTUI front-end for managing `agr` skills: browse `agr.toml`, install/remove skills, preview `SKILL.md`, and run skills via `agrx`. Skill discovery is based on `https://github.com/kasperjunge/agent-resources`.
3
+ # OpenTUI for `agr` and `agrx`
4
+
5
+ An OpenTUI interface for the `agr`/`agrx` CLI: view configured skills, trigger `agr` actions and preview `SKILL.md`
6
+
7
+ [![PyPI](https://img.shields.io/pypi/v/agr-opentui?color=blue)](https://pypi.org/project/agr-opentui/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ </div>
11
+
12
+ ---
13
+
14
+ `agr-opentui` is an OpenTUI front-end for `agr`/`agrx`.
15
+ The default discover source in this repo points to `https://github.com/kasperjunge/agent-resources`.
16
+
17
+ ## Install from PyPI
18
+
19
+ With `uv`:
20
+
21
+ ```bash
22
+ uv tool install agr-opentui
23
+ ```
24
+
25
+ With `pip`:
26
+
27
+ ```bash
28
+ python -m pip install agr-opentui
29
+ ```
30
+
31
+ Then run:
32
+
33
+ ```bash
34
+ agr-opentui
35
+ ```
4
36
 
5
37
  ## Usage
6
38
 
@@ -60,98 +92,50 @@ Discover flow:
60
92
 
61
93
  ## Requirements
62
94
 
63
- Runtime (using `agr-tui`):
95
+ ### Runtime (using `agr-opentui`):
64
96
  - Python 3.10+
65
97
  - `uv`
66
98
  - `agr` + `agrx` on your `PATH`
67
99
 
68
- Build/Development (working on this repo):
100
+ ### Build/Development (working on this repo):
69
101
  - Bun 1.3.8+
70
102
  - Zig (required by OpenTUI build tooling)
71
103
 
72
- ## Install
73
-
74
- ```bash
75
- bun install
76
- ```
77
-
78
- ## Run
79
-
80
- ```bash
81
- bun run src/main.ts
82
- ```
83
-
84
- Run it from the repo you want to manage (the current working directory is the target repo).
85
- `agr.toml` is expected in that target repo for `agr add/remove/sync` operations.
86
-
87
- ### Run From Target Repo
88
-
89
- ```bash
90
- cd /path/to/your/project
91
- agr-tui
92
- ```
93
-
94
- `agr-opentui` itself does not need to contain your target repo's `agr.toml`.
95
-
96
- ## Build
104
+ #### Build
97
105
 
98
106
  ```bash
99
107
  bun run build
100
108
  ```
101
-
102
- This creates `bin/agr-tui`.
103
-
104
- ## Publish to PyPI
105
-
106
- One-time setup:
107
- - Create a `pypi` environment in this GitHub repo.
108
- - In your PyPI project settings, add this repo/workflow as a Trusted Publisher for `.github/workflows/publish-pypi.yml`.
109
- - Optional: add `testpypi` environment and TestPyPI Trusted Publisher too.
110
-
111
- Publish via GitHub Actions:
112
- - Release publish: creating a GitHub release triggers publish to PyPI.
113
- - Manual: run `publish-pypi` workflow and choose `pypi` or `testpypi`.
114
-
115
- Publish from local machine:
116
-
109
+ or
117
110
  ```bash
118
- python -m pip install --upgrade build twine
119
- make py-publish # Upload to PyPI
120
- make py-publish-test # Upload to TestPyPI
111
+ make build
121
112
  ```
113
+ This creates `bin/agr-opentui`.
122
114
 
123
- ## Bump Version
124
115
 
125
- Update package version before creating a release:
126
-
127
- 1. Edit `pyproject.toml` and bump `[project].version`.
128
- 2. Regenerate `uv.lock` so the local package entry matches:
116
+ #### Install
129
117
 
130
118
  ```bash
131
- uv lock
119
+ bun install
132
120
  ```
133
121
 
134
- 3. Run checks:
122
+ #### Run
135
123
 
136
124
  ```bash
137
- make check
125
+ bun run src/main.ts
138
126
  ```
139
127
 
140
- 4. Commit the version bump:
128
+ Run it from the repo you want to manage (the current working directory is the target repo).
129
+ `agr.toml` is expected in that target repo for `agr add/remove/sync` operations.
130
+
131
+ ### Run From Target Repo
141
132
 
142
133
  ```bash
143
- git add pyproject.toml uv.lock
144
- git commit -m "chore: bump version to X.Y.Z"
134
+ cd /path/to/your/project
135
+ agr-opentui
145
136
  ```
146
137
 
147
- 5. Create a GitHub release for `vX.Y.Z` (or manually run `publish-pypi` workflow).
148
-
149
- `publish-pypi.yml` runs automatically when a release is published.
150
-
151
- Alternative: use `.github/workflows/bump-version.yml` via **Actions → bump-version → Run workflow** and provide:
152
- - `version` (required): target version like `0.3.0`
153
- - `branch` (required): target branch to update (default `master`)
154
- - `create_tag` (required, default enabled): creates/pushes tag `v<version>` and creates a GitHub Release
138
+ `agr-opentui` itself does not need to contain your target repo's `agr.toml`.
155
139
 
156
140
  ## Discover List (`skills.json`)
157
141
 
@@ -160,6 +144,8 @@ If `skills.json` exists, the `Discover` tab will list its entries. It supports:
160
144
  - An array of strings or objects (`{ "label": "...", "handle": "...", "repo": "owner/repo" }`).
161
145
  - An object with `source` metadata and `skills` array (see `skills.json` in this repo).
162
146
 
147
+ In this repository, `skills.json` is configured to source skills from `kasperjunge/agent-resources` (`agr.toml` on `main`).
148
+
163
149
  When a `source` is configured, the app checks the remote list periodically (about every 6 hours) and can update `skills.json` using the `u`/`U`/`s`/`S` controls.
164
150
 
165
151
  ## Troubleshooting
@@ -171,7 +157,6 @@ When a `source` is configured, the app checks the remote list periodically (abou
171
157
  - `skills.json not found` or parse errors: fix the file format (array or `{ "source": ..., "skills": [...] }`).
172
158
  - Discover list not updating: check the `source` URL/repo/branch/path and network access.
173
159
  - `SKILL.md` preview says “not found”: the skill may not ship a `SKILL.md` or the path is nonstandard.
174
- - Copy to clipboard doesn’t work: install `pbcopy` (macOS), `wl-copy` (Wayland), or `xclip` (X11).
175
160
 
176
161
  ## Notes
177
162
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agr-opentui"
3
- version = "0.2.2"
3
+ version = "0.3.2"
4
4
  description = "OpenTUI frontend for agr"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -19,7 +19,7 @@ classifiers = [
19
19
  "Topic :: Software Development :: Build Tools",
20
20
  "Topic :: Utilities",
21
21
  ]
22
- requires-python = ">=3.14"
22
+ requires-python = ">=3.14.3"
23
23
  dependencies = [
24
24
  "agr>=0.7.4",
25
25
  ]
@@ -353,6 +353,7 @@ function renderActions(): void {
353
353
  renderActionsWithUi({
354
354
  tab: getActiveTab() === "Discover" ? "Discover" : "Skills",
355
355
  rowCount: actionLines.length,
356
+ updateAvailable: state.updateAvailable,
356
357
  lines: actionLines,
357
358
  });
358
359
  }
@@ -323,9 +323,12 @@ export function buildHelpLines(tab: "Skills" | "Discover"): string[] {
323
323
  ];
324
324
  }
325
325
 
326
- export function buildActionLines(tab: "Skills" | "Discover"): string[] {
326
+ export function buildActionLines(
327
+ tab: "Skills" | "Discover",
328
+ options?: { updateAvailable?: boolean },
329
+ ): string[] {
327
330
  if (tab === "Skills") {
328
- return [
331
+ const lines = [
329
332
  "f: filter list",
330
333
  "p: pin selected",
331
334
  "space: toggle select",
@@ -337,9 +340,6 @@ export function buildActionLines(tab: "Skills" | "Discover"): string[] {
337
340
  "g: run",
338
341
  "G: run options",
339
342
  "u: check updates",
340
- "U: apply update",
341
- "s: apply (confirm)",
342
- "S: apply + sync",
343
343
  "a: add skill",
344
344
  "d: doctor",
345
345
  "T: test popup",
@@ -349,16 +349,18 @@ export function buildActionLines(tab: "Skills" | "Discover"): string[] {
349
349
  "Arrow keys: move",
350
350
  "q: quit",
351
351
  ];
352
+ if (options?.updateAvailable) {
353
+ lines.splice(11, 0, "U: apply update", "s: apply (confirm)", "S: apply + sync");
354
+ }
355
+ return lines;
352
356
  }
353
357
  return [
354
358
  "f: filter list",
355
359
  "p: pin selected",
356
360
  "i: add selected",
357
- "r: remove selected",
358
361
  "z: undo last add/remove",
359
362
  "L: run history",
360
363
  "y: copy handle/repo",
361
- "space: toggle select",
362
364
  "a: add skill",
363
365
  "d: doctor",
364
366
  "T: test popup",
@@ -4,8 +4,9 @@ import { applyRows } from "../ui/rows_render";
4
4
  export function renderActionsWithUi(input: {
5
5
  tab: "Skills" | "Discover";
6
6
  rowCount: number;
7
+ updateAvailable: boolean;
7
8
  lines: Array<{ content: unknown; fg: unknown }>;
8
9
  }): void {
9
- const rows = buildActionRows({ tab: input.tab, rowCount: input.rowCount });
10
+ const rows = buildActionRows({ tab: input.tab, rowCount: input.rowCount, updateAvailable: input.updateAvailable });
10
11
  applyRows(input.lines, rows);
11
12
  }
@@ -166,8 +166,12 @@ export function buildDetailsRows(input: {
166
166
  return rows;
167
167
  }
168
168
 
169
- export function buildActionRows(input: { tab: "Skills" | "Discover"; rowCount: number }): UiRow[] {
170
- const lines = buildActionLines(input.tab);
169
+ export function buildActionRows(input: {
170
+ tab: "Skills" | "Discover";
171
+ rowCount: number;
172
+ updateAvailable?: boolean;
173
+ }): UiRow[] {
174
+ const lines = buildActionLines(input.tab, { updateAvailable: input.updateAvailable });
171
175
  const rows: UiRow[] = [];
172
176
  for (let i = 0; i < input.rowCount; i += 1) {
173
177
  const content = lines[i] ?? "";
@@ -280,7 +284,11 @@ export function buildThreePaneSnapshot(input: {
280
284
  rowCount: 12,
281
285
  });
282
286
 
283
- const actions = buildActionRows({ tab: input.tab, rowCount: 12 });
287
+ const actions = buildActionRows({
288
+ tab: input.tab,
289
+ rowCount: 12,
290
+ updateAvailable: false,
291
+ });
284
292
 
285
293
  return {
286
294
  list: list.rows.map((row) => row.content),
@@ -288,7 +288,7 @@ describe("integration smoke: mocked command run", () => {
288
288
 
289
289
  describe("help/action line snapshots", () => {
290
290
  test("skills action lines stay stable", () => {
291
- expect(buildActionLines("Skills")).toEqual([
291
+ expect(buildActionLines("Skills", { updateAvailable: true })).toEqual([
292
292
  "f: filter list",
293
293
  "p: pin selected",
294
294
  "space: toggle select",
@@ -314,6 +314,30 @@ describe("help/action line snapshots", () => {
314
314
  ]);
315
315
  });
316
316
 
317
+ test("skills action lines hide apply actions when no update is available", () => {
318
+ expect(buildActionLines("Skills", { updateAvailable: false })).toEqual([
319
+ "f: filter list",
320
+ "p: pin selected",
321
+ "space: toggle select",
322
+ "i: install selected",
323
+ "r: remove selected",
324
+ "z: undo last add/remove",
325
+ "L: run history",
326
+ "v: show SKILL",
327
+ "g: run",
328
+ "G: run options",
329
+ "u: check updates",
330
+ "a: add skill",
331
+ "d: doctor",
332
+ "T: test popup",
333
+ "c: reload config",
334
+ "H: help",
335
+ "Tab: next panel",
336
+ "Arrow keys: move",
337
+ "q: quit",
338
+ ]);
339
+ });
340
+
317
341
  test("discover help lines stay stable", () => {
318
342
  expect(buildHelpLines("Discover")).toEqual([
319
343
  "Discover lists skills from skills.json.",
@@ -13,6 +13,7 @@ describe("render actions service", () => {
13
13
  renderActionsWithUi({
14
14
  tab: "Discover",
15
15
  rowCount: lines.length,
16
+ updateAvailable: false,
16
17
  lines,
17
18
  });
18
19
 
@@ -223,4 +223,15 @@ describe("runtime key handler", () => {
223
223
  expect(calls.openRunHistory).toBe(1);
224
224
  expect(calls.undoLastAction).toBe(1);
225
225
  });
226
+
227
+ test("invalid action key on active tab is ignored without blocking next input", () => {
228
+ const { state, calls, handleKey } = createDeps();
229
+ state.tabIndex = 1; // Discover tab
230
+
231
+ expect(handleKey("r")).toBe(false);
232
+ expect(calls.enterInputMode).toHaveLength(0);
233
+
234
+ expect(handleKey("f")).toBe(true);
235
+ expect(calls.enterInputMode).toEqual([{ mode: "filter", seed: "" }]);
236
+ });
226
237
  });
@@ -88,7 +88,7 @@ describe("three-pane render snapshots", () => {
88
88
  selectedIndex: 1,
89
89
  list: [" alpha - org/repo", "> alpha - org/other", ""],
90
90
  details: ["Name: alpha", "Source: org/other", "Handle: org/other/alpha", "Repo: org/other", ""],
91
- actions: ["f: filter list", "p: pin selected", "i: add selected", "r: remove selected", "z: undo last add/remove"],
91
+ actions: ["f: filter list", "p: pin selected", "i: add selected", "z: undo last add/remove", "L: run history"],
92
92
  });
93
93
  });
94
94
  });
@@ -1,6 +1,6 @@
1
1
  version = 1
2
2
  revision = 3
3
- requires-python = ">=3.14"
3
+ requires-python = ">=3.14.3"
4
4
 
5
5
  [[package]]
6
6
  name = "agr"
@@ -19,7 +19,7 @@ wheels = [
19
19
 
20
20
  [[package]]
21
21
  name = "agr-opentui"
22
- version = "0.2.2"
22
+ version = "0.3.2"
23
23
  source = { editable = "." }
24
24
  dependencies = [
25
25
  { name = "agr" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes