reposer 1.3.0 โ 1.4.0
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.
- checksums.yaml +4 -4
- data/AGENTS.md +109 -0
- data/CHANGELOG.md +16 -0
- data/CLAUDE.md +109 -0
- data/Gemfile.lock +1 -1
- data/README.md +12 -1
- data/lib/repose/cli.rb +44 -17
- data/lib/repose/errors.rb +5 -3
- data/lib/repose/github_client.rb +40 -13
- data/lib/repose/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cfd38b233b7fb95d221618d58a19a306959e91896d96990c93e530411037bdb2
|
|
4
|
+
data.tar.gz: 71d6f80d183f237f42a5c6745c1991d02be0fe9445f78e5aa27b243da4127d85
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1d0e5a6272c2911ea0bec13e4bcdcf33fe2e03348ba8e377b10d8ba2d003820638015d483719cfb8930fd111ea3383ff4be04d4524261d465015705c6a04958b
|
|
7
|
+
data.tar.gz: 31452633c4d6e016ac658625a3211d93a5ca66d649259a100745c66cc2bb29f6020dfa6de6a7ecccc02542e1a2422410cb3f07a247b319dcb8184f6480b48a2f
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# CLAUDE.md โ Project Conventions & AI Collaboration Guidelines
|
|
2
|
+
|
|
3
|
+
This file defines standing instructions for Claude when working on any project in this repository. Always read and follow these rules before writing, modifying, or deleting any code or documentation.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ๐๏ธ Planning First
|
|
8
|
+
|
|
9
|
+
- **Always read `PLAN.md`, `ROADMAP.md`, or equivalent planning docs before starting any task.**
|
|
10
|
+
- Identify the relevant phase, step, or milestone before writing or modifying any code.
|
|
11
|
+
- If no plan exists, create one before proceeding and ask for confirmation.
|
|
12
|
+
- After completing work, update `PLAN.md`, `ROADMAP.md`, `README.md`, and any relevant docs to reflect what changed, what's done, and what's next.
|
|
13
|
+
- If a task deviates from the current plan, call it out explicitly before continuing.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## ๐งฑ Code Quality
|
|
18
|
+
|
|
19
|
+
- **All written code must be production-grade at all times.** No placeholders, no "good enough for now," no TODOs left in shipped code.
|
|
20
|
+
- Follow the language's idiomatic style and best practices (e.g., Rust ownership patterns, Python type hints, Go error handling).
|
|
21
|
+
- Prefer explicit over implicit. Avoid magic values โ use named constants.
|
|
22
|
+
- Keep functions small, focused, and single-responsibility.
|
|
23
|
+
- Handle all error cases. Never silently swallow errors.
|
|
24
|
+
- Avoid code duplication. Extract shared logic into reusable utilities or modules.
|
|
25
|
+
- Add inline comments only where intent is non-obvious. Code should be self-documenting first.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## ๐งช Testing
|
|
30
|
+
|
|
31
|
+
- **100% test coverage is required.** Every code file must have a corresponding test file.
|
|
32
|
+
- Tests live alongside their source file or in a dedicated `tests/` directory โ be consistent with the project's convention.
|
|
33
|
+
- Write unit tests for all functions, integration tests for module interactions, and end-to-end tests where applicable.
|
|
34
|
+
- Tests must be deterministic. No flaky tests, no time-dependent assertions without mocking.
|
|
35
|
+
- All tests must pass before committing. Never commit with known failing tests.
|
|
36
|
+
- Use table-driven or parameterized tests for functions with multiple input/output cases.
|
|
37
|
+
- Test edge cases, error paths, and boundary conditions โ not just the happy path.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## ๐ฅ๏ธ Command Output
|
|
42
|
+
|
|
43
|
+
- **Never suppress command output.** Do not use `2>/dev/null`, `2>&1`, `--quiet`, `-q`, or any flag that hides stderr/stdout unless the user explicitly requests it.
|
|
44
|
+
- All command output must be visible so failures, hangs, warnings, and progress can be assessed in real time.
|
|
45
|
+
- If a command is long-running, prefer flags that show progress (e.g., `--verbose`, `-v`) where available.
|
|
46
|
+
- If a command hangs, report it โ do not silently wait indefinitely.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## ๐ Git Workflow
|
|
51
|
+
|
|
52
|
+
- **At the end of every completed prompt, if all tests pass: `git add`, `git commit`, and `git push`.**
|
|
53
|
+
- Write clear, imperative commit messages that describe *what* and *why*:
|
|
54
|
+
- โ
`feat(inference): add KV cache eviction strategy for M3 memory pressure`
|
|
55
|
+
- โ `updates`, `fix stuff`, `WIP`
|
|
56
|
+
- Follow [Conventional Commits](https://www.conventionalcommits.org/) format: `type(scope): description`
|
|
57
|
+
- Types: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `perf`, `ci`
|
|
58
|
+
- Never force-push to `main` or `master` without explicit instruction.
|
|
59
|
+
- Commit logical units of work โ don't bundle unrelated changes in one commit.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## ๐ File & Project Structure
|
|
64
|
+
|
|
65
|
+
- Follow the existing project structure. Do not reorganize directories without discussing it first.
|
|
66
|
+
- New modules, crates, or packages should match the naming convention already in use.
|
|
67
|
+
- Keep config, secrets, and environment-specific values out of source code. Use `.env` files or environment variables, and ensure `.gitignore` is up to date.
|
|
68
|
+
- Delete dead code. Don't comment it out and leave it โ use version control for history.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## ๐ Documentation
|
|
73
|
+
|
|
74
|
+
- Update `README.md` whenever public-facing behavior, setup steps, or architecture changes.
|
|
75
|
+
- Update `PLAN.md` / `ROADMAP.md` after every session โ mark completed items, add new findings, note blockers.
|
|
76
|
+
- Document all public APIs, functions, and types with docstrings/doc comments appropriate to the language.
|
|
77
|
+
- If a non-obvious architectural decision is made, add an `ADR` (Architecture Decision Record) entry or a note in the relevant doc.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## ๐ Before You Build
|
|
82
|
+
|
|
83
|
+
Before writing any code, confirm:
|
|
84
|
+
1. โ
You've read the relevant plan/phase/step.
|
|
85
|
+
2. โ
You understand what "done" looks like for this task.
|
|
86
|
+
3. โ
You know where the new code lives in the project structure.
|
|
87
|
+
4. โ
You know what tests will prove it works.
|
|
88
|
+
5. โ
You know what docs need updating when it's done.
|
|
89
|
+
|
|
90
|
+
If any of these are unclear, ask before proceeding.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## ๐ซ Hard Stops
|
|
95
|
+
|
|
96
|
+
Do not proceed if:
|
|
97
|
+
- Tests are failing from a previous step (fix them first).
|
|
98
|
+
- The plan is ambiguous or missing for a non-trivial task.
|
|
99
|
+
- A change would break a public API or interface without a migration path.
|
|
100
|
+
- A required dependency is unavailable or untested on the target platform.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## ๐ง General Mindset
|
|
105
|
+
|
|
106
|
+
- Prefer boring, correct, and maintainable over clever.
|
|
107
|
+
- When in doubt, do less and confirm โ don't assume scope.
|
|
108
|
+
- Surface trade-offs and alternatives when they exist; don't just pick one silently.
|
|
109
|
+
- Treat every PR as if a senior engineer on the team will review it.
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.4.0] - 2026-03-11
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Organization & Namespace Selection**: Choose where to create a new repository
|
|
14
|
+
- Fetches the authenticated user's personal account and all GitHub organization memberships via the API
|
|
15
|
+
- Presents an interactive `Create repository under:` selection prompt when multiple namespaces are available
|
|
16
|
+
- Automatically skips the prompt when the user has no org memberships (personal account only)
|
|
17
|
+
- New `--org ORG` CLI flag to specify the destination directly (bypasses the prompt for scripted use)
|
|
18
|
+
- Gracefully falls back to personal account if namespace fetching fails
|
|
19
|
+
- Preview output now shows `Destination: owner/repo-name` so the target is visible before confirming
|
|
20
|
+
- **`GitHubClient#available_namespaces`**: New public method returning personal + org namespaces
|
|
21
|
+
- **`GitHubClient#repository_exists?`**: Now accepts an optional `owner` parameter
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- `GitHubClient#create_repository` accepts a new `owner:` keyword argument; passes `organization:` to the GitHub API when creating under an org
|
|
25
|
+
|
|
10
26
|
## [1.3.0] - 2025-11-21
|
|
11
27
|
|
|
12
28
|
### Added
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# CLAUDE.md โ Project Conventions & AI Collaboration Guidelines
|
|
2
|
+
|
|
3
|
+
This file defines standing instructions for Claude when working on any project in this repository. Always read and follow these rules before writing, modifying, or deleting any code or documentation.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ๐๏ธ Planning First
|
|
8
|
+
|
|
9
|
+
- **Always read `PLAN.md`, `ROADMAP.md`, or equivalent planning docs before starting any task.**
|
|
10
|
+
- Identify the relevant phase, step, or milestone before writing or modifying any code.
|
|
11
|
+
- If no plan exists, create one before proceeding and ask for confirmation.
|
|
12
|
+
- After completing work, update `PLAN.md`, `ROADMAP.md`, `README.md`, and any relevant docs to reflect what changed, what's done, and what's next.
|
|
13
|
+
- If a task deviates from the current plan, call it out explicitly before continuing.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## ๐งฑ Code Quality
|
|
18
|
+
|
|
19
|
+
- **All written code must be production-grade at all times.** No placeholders, no "good enough for now," no TODOs left in shipped code.
|
|
20
|
+
- Follow the language's idiomatic style and best practices (e.g., Rust ownership patterns, Python type hints, Go error handling).
|
|
21
|
+
- Prefer explicit over implicit. Avoid magic values โ use named constants.
|
|
22
|
+
- Keep functions small, focused, and single-responsibility.
|
|
23
|
+
- Handle all error cases. Never silently swallow errors.
|
|
24
|
+
- Avoid code duplication. Extract shared logic into reusable utilities or modules.
|
|
25
|
+
- Add inline comments only where intent is non-obvious. Code should be self-documenting first.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## ๐งช Testing
|
|
30
|
+
|
|
31
|
+
- **100% test coverage is required.** Every code file must have a corresponding test file.
|
|
32
|
+
- Tests live alongside their source file or in a dedicated `tests/` directory โ be consistent with the project's convention.
|
|
33
|
+
- Write unit tests for all functions, integration tests for module interactions, and end-to-end tests where applicable.
|
|
34
|
+
- Tests must be deterministic. No flaky tests, no time-dependent assertions without mocking.
|
|
35
|
+
- All tests must pass before committing. Never commit with known failing tests.
|
|
36
|
+
- Use table-driven or parameterized tests for functions with multiple input/output cases.
|
|
37
|
+
- Test edge cases, error paths, and boundary conditions โ not just the happy path.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## ๐ฅ๏ธ Command Output
|
|
42
|
+
|
|
43
|
+
- **Never suppress command output.** Do not use `2>/dev/null`, `2>&1`, `--quiet`, `-q`, or any flag that hides stderr/stdout unless the user explicitly requests it.
|
|
44
|
+
- All command output must be visible so failures, hangs, warnings, and progress can be assessed in real time.
|
|
45
|
+
- If a command is long-running, prefer flags that show progress (e.g., `--verbose`, `-v`) where available.
|
|
46
|
+
- If a command hangs, report it โ do not silently wait indefinitely.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## ๐ Git Workflow
|
|
51
|
+
|
|
52
|
+
- **At the end of every completed prompt, if all tests pass: `git add`, `git commit`, and `git push`.**
|
|
53
|
+
- Write clear, imperative commit messages that describe *what* and *why*:
|
|
54
|
+
- โ
`feat(inference): add KV cache eviction strategy for M3 memory pressure`
|
|
55
|
+
- โ `updates`, `fix stuff`, `WIP`
|
|
56
|
+
- Follow [Conventional Commits](https://www.conventionalcommits.org/) format: `type(scope): description`
|
|
57
|
+
- Types: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `perf`, `ci`
|
|
58
|
+
- Never force-push to `main` or `master` without explicit instruction.
|
|
59
|
+
- Commit logical units of work โ don't bundle unrelated changes in one commit.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## ๐ File & Project Structure
|
|
64
|
+
|
|
65
|
+
- Follow the existing project structure. Do not reorganize directories without discussing it first.
|
|
66
|
+
- New modules, crates, or packages should match the naming convention already in use.
|
|
67
|
+
- Keep config, secrets, and environment-specific values out of source code. Use `.env` files or environment variables, and ensure `.gitignore` is up to date.
|
|
68
|
+
- Delete dead code. Don't comment it out and leave it โ use version control for history.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## ๐ Documentation
|
|
73
|
+
|
|
74
|
+
- Update `README.md` whenever public-facing behavior, setup steps, or architecture changes.
|
|
75
|
+
- Update `PLAN.md` / `ROADMAP.md` after every session โ mark completed items, add new findings, note blockers.
|
|
76
|
+
- Document all public APIs, functions, and types with docstrings/doc comments appropriate to the language.
|
|
77
|
+
- If a non-obvious architectural decision is made, add an `ADR` (Architecture Decision Record) entry or a note in the relevant doc.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## ๐ Before You Build
|
|
82
|
+
|
|
83
|
+
Before writing any code, confirm:
|
|
84
|
+
1. โ
You've read the relevant plan/phase/step.
|
|
85
|
+
2. โ
You understand what "done" looks like for this task.
|
|
86
|
+
3. โ
You know where the new code lives in the project structure.
|
|
87
|
+
4. โ
You know what tests will prove it works.
|
|
88
|
+
5. โ
You know what docs need updating when it's done.
|
|
89
|
+
|
|
90
|
+
If any of these are unclear, ask before proceeding.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## ๐ซ Hard Stops
|
|
95
|
+
|
|
96
|
+
Do not proceed if:
|
|
97
|
+
- Tests are failing from a previous step (fix them first).
|
|
98
|
+
- The plan is ambiguous or missing for a non-trivial task.
|
|
99
|
+
- A change would break a public API or interface without a migration path.
|
|
100
|
+
- A required dependency is unavailable or untested on the target platform.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## ๐ง General Mindset
|
|
105
|
+
|
|
106
|
+
- Prefer boring, correct, and maintainable over clever.
|
|
107
|
+
- When in doubt, do less and confirm โ don't assume scope.
|
|
108
|
+
- Surface trade-offs and alternatives when they exist; don't just pick one silently.
|
|
109
|
+
- Treat every PR as if a senior engineer on the team will review it.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -20,6 +20,7 @@ Reposer is an intelligent CLI tool that uses AI to create GitHub repositories wi
|
|
|
20
20
|
- **๐ท๏ธ 20 Intelligent Topics**: Generates up to 20 relevant tags and topics automatically
|
|
21
21
|
- **๐ Emoji Support**: Automatic emoji inclusion in descriptions and READMEs for visual appeal
|
|
22
22
|
- **๐ License Selection**: Interactive license picker (MIT, Apache, GPL, BSD, MPL, Unlicense)
|
|
23
|
+
- **๐ข Organization Support**: Choose to create repos under your personal account or any GitHub org you belong to
|
|
23
24
|
- **๐๏ธ Language-Specific Project Files**: Auto-generates boilerplate files (go.mod, package.json, requirements.txt, etc.)
|
|
24
25
|
- **๐๏ธ Preview Mode**: See generated content before creating repository
|
|
25
26
|
- **๐ Secure Configuration**: Encrypted storage of API keys and tokens
|
|
@@ -112,6 +113,12 @@ reposer create ai-chatbot --language python --framework fastapi --dry-run
|
|
|
112
113
|
# Specify license type
|
|
113
114
|
reposer create api-server --language go --framework gin --license apache-2.0
|
|
114
115
|
|
|
116
|
+
# Create under a GitHub organization
|
|
117
|
+
reposer create team-tool --language ruby --org my-company
|
|
118
|
+
|
|
119
|
+
# Create under an org with full options
|
|
120
|
+
reposer create infra-scripts --language python --org devops-team --private --license mit
|
|
121
|
+
|
|
115
122
|
# Custom description and topics
|
|
116
123
|
reposer create data-processor \
|
|
117
124
|
--language python \
|
|
@@ -127,6 +134,7 @@ reposer create blog-api --language ruby --framework rails --license gpl-3.0 --pr
|
|
|
127
134
|
$ reposer create awesome-api
|
|
128
135
|
๐ฏ Reposer - AI Repository Creator
|
|
129
136
|
========================================
|
|
137
|
+
Create repository under: yourusername (personal)
|
|
130
138
|
Primary programming language: ruby
|
|
131
139
|
Framework/Library: Rails
|
|
132
140
|
Choose a license: MIT License (Permissive, most popular)
|
|
@@ -134,6 +142,7 @@ What will this project do? A REST API for user management
|
|
|
134
142
|
|
|
135
143
|
๐ Generated Repository Content
|
|
136
144
|
----------------------------------------
|
|
145
|
+
Destination: yourusername/awesome-api
|
|
137
146
|
Name: awesome-api
|
|
138
147
|
Description: ๐ A Ruby Rails REST API for user management ๐
|
|
139
148
|
Topics: ruby, rails, api, rest, web, backend, database, authentication,
|
|
@@ -204,9 +213,10 @@ Create a new repository with AI assistance.
|
|
|
204
213
|
|
|
205
214
|
**Options:**
|
|
206
215
|
- `--language LANG` - Primary programming language
|
|
207
|
-
- `--framework FRAMEWORK` - Framework or library to use
|
|
216
|
+
- `--framework FRAMEWORK` - Framework or library to use
|
|
208
217
|
- `--description TEXT` - Custom description override
|
|
209
218
|
- `--license LICENSE` - License type (mit, apache-2.0, gpl-3.0, bsd-3-clause, mpl-2.0, unlicense)
|
|
219
|
+
- `--org ORG` - GitHub organization or user login to create the repository under (skips interactive selection)
|
|
210
220
|
- `--private` - Create private repository (default: public)
|
|
211
221
|
- `--topics TOPIC1,TOPIC2` - Custom topics/tags (up to 20)
|
|
212
222
|
- `--dry-run` - Preview without creating
|
|
@@ -218,6 +228,7 @@ reposer create web-app --language typescript --framework react
|
|
|
218
228
|
reposer create microservice --language go --license apache-2.0 --private
|
|
219
229
|
reposer create ml-model --language python --topics ml,ai,data-science --dry-run
|
|
220
230
|
reposer create api-server --language ruby --framework rails --license gpl-3.0
|
|
231
|
+
reposer create team-tool --language python --org my-company
|
|
221
232
|
```
|
|
222
233
|
|
|
223
234
|
### `repose configure`
|
data/lib/repose/cli.rb
CHANGED
|
@@ -21,6 +21,7 @@ module Repose
|
|
|
21
21
|
$ repose create my-awesome-project
|
|
22
22
|
$ repose create web-scraper --language ruby --framework rails
|
|
23
23
|
$ repose create api-server --license apache-2.0
|
|
24
|
+
$ repose create team-tool --org my-org
|
|
24
25
|
DESC
|
|
25
26
|
option :language, type: :string, desc: "Primary programming language"
|
|
26
27
|
option :framework, type: :string, desc: "Framework or library to use"
|
|
@@ -30,6 +31,7 @@ module Repose
|
|
|
30
31
|
option :topics, type: :array, desc: "Custom topics/tags"
|
|
31
32
|
option :license, type: :string, desc: "License type (mit, apache-2.0, gpl-3.0, bsd-3-clause, unlicense, etc.)"
|
|
32
33
|
option :dry_run, type: :boolean, default: false, desc: "Preview without creating"
|
|
34
|
+
option :org, type: :string, desc: "Organization or user login to create the repository under (skips interactive selection)"
|
|
33
35
|
def create(name = nil)
|
|
34
36
|
pastel = Pastel.new
|
|
35
37
|
prompt = TTY::Prompt.new
|
|
@@ -42,9 +44,12 @@ module Repose
|
|
|
42
44
|
q.validate(/\A[a-zA-Z0-9._-]+\z/, "Invalid repository name format")
|
|
43
45
|
end
|
|
44
46
|
|
|
47
|
+
# Determine the owner (org or personal account)
|
|
48
|
+
owner = options[:org] || select_namespace(prompt, pastel)
|
|
49
|
+
|
|
45
50
|
# Gather context
|
|
46
51
|
context = gather_context(name, options, prompt)
|
|
47
|
-
|
|
52
|
+
|
|
48
53
|
# Generate AI content
|
|
49
54
|
spinner = TTY::Spinner.new("[:spinner] Generating repository content with AI...", format: :dots)
|
|
50
55
|
spinner.auto_spin
|
|
@@ -59,12 +64,12 @@ module Repose
|
|
|
59
64
|
end
|
|
60
65
|
|
|
61
66
|
# Display preview
|
|
62
|
-
display_preview(ai_content, pastel)
|
|
67
|
+
display_preview(ai_content, pastel, owner)
|
|
63
68
|
|
|
64
69
|
# Confirm creation
|
|
65
70
|
unless options[:dry_run]
|
|
66
71
|
if prompt.yes?("Create repository?")
|
|
67
|
-
create_repository(name, ai_content, options, pastel)
|
|
72
|
+
create_repository(name, ai_content, options, pastel, owner)
|
|
68
73
|
else
|
|
69
74
|
puts pastel.yellow("Repository creation cancelled.")
|
|
70
75
|
end
|
|
@@ -98,6 +103,25 @@ module Repose
|
|
|
98
103
|
|
|
99
104
|
private
|
|
100
105
|
|
|
106
|
+
# Fetches the authenticated user's personal account and all orgs they belong
|
|
107
|
+
# to, then prompts the user to choose where to create the new repository.
|
|
108
|
+
# Returns nil (personal account default) when there is only one namespace
|
|
109
|
+
# available or when the namespace list cannot be fetched.
|
|
110
|
+
def select_namespace(prompt, pastel)
|
|
111
|
+
github_client = GitHubClient.new
|
|
112
|
+
namespaces = github_client.available_namespaces
|
|
113
|
+
|
|
114
|
+
# No choice needed when the user has no org memberships
|
|
115
|
+
return nil if namespaces.size == 1
|
|
116
|
+
|
|
117
|
+
selected = prompt.select("Create repository under:", namespaces)
|
|
118
|
+
# nil signals "personal account" to create_repository
|
|
119
|
+
selected == namespaces.first[:value] ? nil : selected
|
|
120
|
+
rescue Errors::AuthenticationError, Errors::GitHubError => e
|
|
121
|
+
puts pastel.yellow("Warning: could not fetch organizations (#{e.message}). Defaulting to personal account.")
|
|
122
|
+
nil
|
|
123
|
+
end
|
|
124
|
+
|
|
101
125
|
def gather_context(name, options, prompt)
|
|
102
126
|
context = {
|
|
103
127
|
name: name,
|
|
@@ -134,7 +158,7 @@ module Repose
|
|
|
134
158
|
{ name: "Other/Custom", value: "other" }
|
|
135
159
|
]
|
|
136
160
|
context[:license] = prompt.select("Choose a license:", licenses)
|
|
137
|
-
|
|
161
|
+
|
|
138
162
|
if context[:license] == "other"
|
|
139
163
|
context[:license] = prompt.ask("Enter license name:", default: "MIT")
|
|
140
164
|
end
|
|
@@ -142,7 +166,7 @@ module Repose
|
|
|
142
166
|
|
|
143
167
|
# Additional context
|
|
144
168
|
context[:purpose] = prompt.ask("What will this project do? (optional):")
|
|
145
|
-
|
|
169
|
+
|
|
146
170
|
context
|
|
147
171
|
end
|
|
148
172
|
|
|
@@ -167,21 +191,23 @@ module Repose
|
|
|
167
191
|
frameworks[language] || []
|
|
168
192
|
end
|
|
169
193
|
|
|
170
|
-
def display_preview(content, pastel)
|
|
194
|
+
def display_preview(content, pastel, owner = nil)
|
|
171
195
|
puts "\n" + pastel.cyan("๐ Generated Repository Content")
|
|
172
196
|
puts pastel.dim("-" * 40)
|
|
173
|
-
|
|
197
|
+
|
|
198
|
+
destination = owner ? "#{owner}/#{content[:name]}" : content[:name]
|
|
199
|
+
puts pastel.bold("Destination: ") + destination
|
|
174
200
|
puts pastel.bold("Name: ") + content[:name]
|
|
175
201
|
puts pastel.bold("Description: ") + content[:description]
|
|
176
202
|
puts pastel.bold("License: ") + (content[:license] || "MIT").upcase
|
|
177
203
|
puts pastel.bold("Topics: ") + content[:topics].join(", ")
|
|
178
|
-
|
|
204
|
+
|
|
179
205
|
puts "\n" + pastel.bold("README Preview:")
|
|
180
206
|
puts pastel.dim(content[:readme][0..300] + "...")
|
|
181
207
|
puts
|
|
182
208
|
end
|
|
183
209
|
|
|
184
|
-
def create_repository(name, content, options, pastel)
|
|
210
|
+
def create_repository(name, content, options, pastel, owner = nil)
|
|
185
211
|
spinner = TTY::Spinner.new("[:spinner] Creating GitHub repository...", format: :dots)
|
|
186
212
|
spinner.auto_spin
|
|
187
213
|
|
|
@@ -193,22 +219,23 @@ module Repose
|
|
|
193
219
|
private: options[:private],
|
|
194
220
|
topics: content[:topics],
|
|
195
221
|
readme: content[:readme],
|
|
196
|
-
license: content[:license]
|
|
222
|
+
license: content[:license],
|
|
223
|
+
owner: owner
|
|
197
224
|
)
|
|
198
|
-
|
|
225
|
+
|
|
199
226
|
spinner.success("โ
")
|
|
200
|
-
|
|
227
|
+
|
|
201
228
|
# Create language-specific project files
|
|
202
229
|
project_files = ProjectFilesGenerator.generate(
|
|
203
230
|
language: content[:language],
|
|
204
231
|
framework: content[:framework],
|
|
205
232
|
name: name
|
|
206
233
|
)
|
|
207
|
-
|
|
234
|
+
|
|
208
235
|
if project_files.any?
|
|
209
236
|
file_spinner = TTY::Spinner.new("[:spinner] Adding project files...", format: :dots)
|
|
210
237
|
file_spinner.auto_spin
|
|
211
|
-
|
|
238
|
+
|
|
212
239
|
project_files.each do |file_path, file_content|
|
|
213
240
|
github_client.create_file(
|
|
214
241
|
repo.full_name,
|
|
@@ -217,10 +244,10 @@ module Repose
|
|
|
217
244
|
file_content
|
|
218
245
|
)
|
|
219
246
|
end
|
|
220
|
-
|
|
247
|
+
|
|
221
248
|
file_spinner.success("โ
")
|
|
222
249
|
end
|
|
223
|
-
|
|
250
|
+
|
|
224
251
|
puts pastel.green("Repository created successfully!")
|
|
225
252
|
puts pastel.cyan("๐ #{repo.html_url}")
|
|
226
253
|
rescue => e
|
|
@@ -230,4 +257,4 @@ module Repose
|
|
|
230
257
|
end
|
|
231
258
|
end
|
|
232
259
|
end
|
|
233
|
-
end
|
|
260
|
+
end
|
data/lib/repose/errors.rb
CHANGED
|
@@ -4,14 +4,16 @@ module Repose
|
|
|
4
4
|
module Errors
|
|
5
5
|
class Error < StandardError; end
|
|
6
6
|
class ConfigError < Error; end
|
|
7
|
+
class ConfigurationError < Error; end
|
|
7
8
|
class GitHubError < Error; end
|
|
9
|
+
class AuthenticationError < Error; end
|
|
8
10
|
class AIError < Error; end
|
|
9
11
|
class ValidationError < Error; end
|
|
10
12
|
end
|
|
11
13
|
|
|
12
|
-
# Convenience aliases for AI providers
|
|
13
|
-
ConfigurationError = Errors::
|
|
14
|
+
# Convenience aliases for AI providers at module level
|
|
15
|
+
ConfigurationError = Errors::ConfigurationError
|
|
14
16
|
APIError = Errors::AIError
|
|
15
|
-
AuthenticationError = Errors::
|
|
17
|
+
AuthenticationError = Errors::AuthenticationError
|
|
16
18
|
RateLimitError = Errors::AIError
|
|
17
19
|
end
|
data/lib/repose/github_client.rb
CHANGED
|
@@ -5,16 +5,34 @@ require "octokit"
|
|
|
5
5
|
module Repose
|
|
6
6
|
class GitHubClient
|
|
7
7
|
def initialize
|
|
8
|
-
token = Repose.config.github_token || ENV["
|
|
9
|
-
|
|
10
|
-
raise Errors::ConfigurationError, "GitHub token not configured. Set
|
|
11
|
-
|
|
8
|
+
token = Repose.config.github_token || ENV["REPOSE_TOKEN"]
|
|
9
|
+
|
|
10
|
+
raise Errors::ConfigurationError, "GitHub token not configured. Set REPOSE_TOKEN environment variable or run 'repose configure'" if token.nil? || token.empty?
|
|
11
|
+
|
|
12
12
|
@client = Octokit::Client.new(access_token: token)
|
|
13
13
|
@client.auto_paginate = true
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
# Returns an array of namespace hashes (personal account + orgs) the
|
|
17
|
+
# authenticated user can create repositories under. Each element has the
|
|
18
|
+
# shape: { name: "display label", value: "login" }.
|
|
19
|
+
def available_namespaces
|
|
20
|
+
user = @client.user
|
|
21
|
+
orgs = @client.organizations
|
|
22
|
+
|
|
23
|
+
namespaces = [{ name: "#{user.login} (personal)", value: user.login }]
|
|
24
|
+
orgs.each do |org|
|
|
25
|
+
namespaces << { name: org.login, value: org.login }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
namespaces
|
|
29
|
+
rescue Octokit::Unauthorized => e
|
|
30
|
+
raise Errors::AuthenticationError, "GitHub authentication failed: #{e.message}"
|
|
31
|
+
rescue Octokit::Error => e
|
|
32
|
+
raise Errors::GitHubError, "Failed to fetch organizations: #{e.message}"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def create_repository(name:, description:, private: false, topics: [], readme: nil, license: nil, owner: nil)
|
|
18
36
|
repo_options = {
|
|
19
37
|
description: description,
|
|
20
38
|
private: private,
|
|
@@ -23,12 +41,17 @@ module Repose
|
|
|
23
41
|
has_wiki: true,
|
|
24
42
|
has_projects: true
|
|
25
43
|
}
|
|
26
|
-
|
|
44
|
+
|
|
27
45
|
# Add license template if specified
|
|
28
46
|
if license && !license.empty?
|
|
29
47
|
repo_options[:license_template] = normalize_license_key(license)
|
|
30
48
|
end
|
|
31
|
-
|
|
49
|
+
|
|
50
|
+
# Create under an org when the owner differs from the authenticated user
|
|
51
|
+
unless owner.nil? || owner.empty? || owner == current_user_login
|
|
52
|
+
repo_options[:organization] = owner
|
|
53
|
+
end
|
|
54
|
+
|
|
32
55
|
repo = @client.create_repository(name, repo_options)
|
|
33
56
|
|
|
34
57
|
# Add topics if provided
|
|
@@ -56,9 +79,9 @@ module Repose
|
|
|
56
79
|
raise Errors::GitHubError, "GitHub API error: #{e.message}"
|
|
57
80
|
end
|
|
58
81
|
|
|
59
|
-
def repository_exists?(name)
|
|
60
|
-
|
|
61
|
-
@client.repository?("#{
|
|
82
|
+
def repository_exists?(name, owner = nil)
|
|
83
|
+
namespace = owner || current_user_login
|
|
84
|
+
@client.repository?("#{namespace}/#{name}")
|
|
62
85
|
rescue Octokit::NotFound
|
|
63
86
|
false
|
|
64
87
|
rescue Octokit::Unauthorized => e
|
|
@@ -89,6 +112,10 @@ module Repose
|
|
|
89
112
|
|
|
90
113
|
private
|
|
91
114
|
|
|
115
|
+
def current_user_login
|
|
116
|
+
@current_user_login ||= @client.user.login
|
|
117
|
+
end
|
|
118
|
+
|
|
92
119
|
def normalize_license_key(license)
|
|
93
120
|
# GitHub API uses specific license keys
|
|
94
121
|
license_map = {
|
|
@@ -103,9 +130,9 @@ module Repose
|
|
|
103
130
|
"mpl-2.0" => "mpl-2.0",
|
|
104
131
|
"unlicense" => "unlicense"
|
|
105
132
|
}
|
|
106
|
-
|
|
133
|
+
|
|
107
134
|
normalized = license_map[license.downcase] || license.downcase
|
|
108
135
|
normalized
|
|
109
136
|
end
|
|
110
137
|
end
|
|
111
|
-
end
|
|
138
|
+
end
|
data/lib/repose/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: reposer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Wesley Scholl
|
|
@@ -133,7 +133,9 @@ files:
|
|
|
133
133
|
- ".rspec"
|
|
134
134
|
- ".rubocop.yml"
|
|
135
135
|
- ".ruby-version"
|
|
136
|
+
- AGENTS.md
|
|
136
137
|
- CHANGELOG.md
|
|
138
|
+
- CLAUDE.md
|
|
137
139
|
- Gemfile
|
|
138
140
|
- Gemfile.lock
|
|
139
141
|
- LICENSE
|