assistant 0.0.2 → 1.0.0.rc1
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/.editorconfig +13 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +39 -0
- data/.github/dependabot.yml +4 -0
- data/.github/workflows/ci.yml +140 -0
- data/.github/workflows/docs.yml +64 -0
- data/.github/workflows/release.yml +46 -0
- data/.gitignore +5 -1
- data/.markdownlint.json +6 -0
- data/.opencode/.gitignore +4 -0
- data/.opencode/opencode.json +13 -0
- data/.opencode/skills/create-pr/SKILL.md +138 -0
- data/.opencode/skills/ruby-services/SKILL.md +81 -0
- data/.rubocop.yml +40 -148
- data/.ruby-version +1 -1
- data/.yardopts +17 -0
- data/CHANGELOG.md +434 -0
- data/CONTRIBUTING.md +131 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +264 -94
- data/README.md +125 -16
- data/Rakefile +53 -3
- data/SECURITY.md +50 -0
- data/Steepfile +49 -0
- data/_config.yml +87 -0
- data/assistant.gemspec +33 -20
- data/docs/api-reference.md +264 -0
- data/docs/changelog.md +26 -0
- data/docs/deprecations.md +86 -0
- data/docs/examples/cli-handler.md +17 -0
- data/docs/examples/composing-services.md +17 -0
- data/docs/examples/execute-callbacks.md +17 -0
- data/docs/examples/index.md +29 -0
- data/docs/examples/instrumentation-notifier.md +17 -0
- data/docs/examples/rails-service.md +17 -0
- data/docs/examples/rbs-generator.md +17 -0
- data/docs/examples/sidekiq-worker.md +17 -0
- data/docs/getting-started.md +136 -0
- data/docs/guides/composing-services.md +222 -0
- data/docs/guides/index.md +25 -0
- data/docs/guides/inputs.md +333 -0
- data/docs/guides/logging-and-results.md +202 -0
- data/docs/guides/rbs-and-types.md +16 -0
- data/docs/guides/validation.md +180 -0
- data/docs/index.md +69 -0
- data/docs/roadmap.md +33 -0
- data/exe/assistant-rbs +7 -0
- data/lib/assistant/execute_callbacks.rb +103 -0
- data/lib/assistant/execute_callbacks.rbs +30 -0
- data/lib/assistant/input_builder/accessors.rb +36 -0
- data/lib/assistant/input_builder/accessors.rbs +10 -0
- data/lib/assistant/input_builder/default_option.rb +41 -0
- data/lib/assistant/input_builder/default_option.rbs +11 -0
- data/lib/assistant/input_builder/dsl.rb +37 -0
- data/lib/assistant/input_builder/dsl.rbs +12 -0
- data/lib/assistant/input_builder/optional_option.rb +45 -0
- data/lib/assistant/input_builder/optional_option.rbs +10 -0
- data/lib/assistant/input_builder/registry.rb +27 -0
- data/lib/assistant/input_builder/registry.rbs +13 -0
- data/lib/assistant/input_builder/require_validator.rb +104 -0
- data/lib/assistant/input_builder/require_validator.rbs +24 -0
- data/lib/assistant/input_builder/type_validator.rb +47 -0
- data/lib/assistant/input_builder/type_validator.rbs +18 -0
- data/lib/assistant/input_builder.rb +28 -0
- data/lib/assistant/input_builder.rbs +15 -0
- data/lib/assistant/log_item.rb +75 -17
- data/lib/assistant/log_item.rbs +40 -0
- data/lib/assistant/log_list.rb +44 -12
- data/lib/assistant/log_list.rbs +48 -0
- data/lib/assistant/rbs_generator/cli.rb +109 -0
- data/lib/assistant/rbs_generator/cli.rbs +24 -0
- data/lib/assistant/rbs_generator/renderer.rb +67 -0
- data/lib/assistant/rbs_generator/renderer.rbs +11 -0
- data/lib/assistant/rbs_generator/writer.rb +65 -0
- data/lib/assistant/rbs_generator/writer.rbs +24 -0
- data/lib/assistant/rbs_generator.rb +38 -0
- data/lib/assistant/rbs_generator.rbs +5 -0
- data/lib/assistant/refinements/string_blankness.rb +14 -0
- data/lib/assistant/refinements/string_blankness.rbs +6 -0
- data/lib/assistant/service.rb +328 -8
- data/lib/assistant/service.rbs +86 -0
- data/lib/assistant/version.rb +5 -1
- data/lib/assistant/version.rbs +5 -0
- data/lib/assistant.rb +53 -4
- data/lib/assistant.rbs +25 -0
- data/mise.toml +6 -0
- data/sig/examples/greeter.rbs +14 -0
- metadata +128 -112
- data/.circleci/config.yml +0 -45
- data/.fasterer.yml +0 -19
- data/.rspec +0 -3
- data/.rubocop_todo.yml +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6b4eab141f258e58024dcc2805a4030321835b45853cf915d8a8c48aa9849144
|
|
4
|
+
data.tar.gz: 354914c47054404c57ef636d46316e0ee8cb491305ab9c081a0628e4a30708c5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ced1f45ddcc684272b2858aebead07ee968823cdf0c52bf71877cf283b1881fec66e59b7f9c56538d5c9ba949abac3c425083c1334947bc0572235dea1ed0b92
|
|
7
|
+
data.tar.gz: 64bde79e3880ac363fc31e0d37dcae5e4e3657ec4f55807385378e3f59699fb211204a1fdf8339d4e8dc9e5d4ce8dad1bb71e82d5c6b845c1697dbc136cc99ba
|
data/.editorconfig
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# EditorConfig is awesome: https://EditorConfig.org
|
|
2
|
+
|
|
3
|
+
# top-most EditorConfig file
|
|
4
|
+
root = true
|
|
5
|
+
|
|
6
|
+
[*]
|
|
7
|
+
indent_style = space
|
|
8
|
+
indent_size = 2
|
|
9
|
+
end_of_line = lf
|
|
10
|
+
charset = utf-8
|
|
11
|
+
trim_trailing_whitespace = true
|
|
12
|
+
insert_final_newline = true
|
|
13
|
+
quote_type = single
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!-- markdownlint-disable MD013 -->
|
|
2
|
+
## Scope
|
|
3
|
+
|
|
4
|
+
<!--
|
|
5
|
+
Which roadmap milestone or issue does this PR implement?
|
|
6
|
+
Link the relevant `docs/v1/*.md` line or the GitHub issue.
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
## What this PR ships
|
|
10
|
+
|
|
11
|
+
<!--
|
|
12
|
+
Bullet list of the public-facing changes.
|
|
13
|
+
-->
|
|
14
|
+
|
|
15
|
+
-
|
|
16
|
+
|
|
17
|
+
## Verification
|
|
18
|
+
|
|
19
|
+
<!--
|
|
20
|
+
Paste the tail of the local pipeline (or just confirm rake ci is green).
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
bundle exec rake ci
|
|
24
|
+
```
|
|
25
|
+
-->
|
|
26
|
+
|
|
27
|
+
## Out of scope
|
|
28
|
+
|
|
29
|
+
<!--
|
|
30
|
+
Anything that was deliberately left for a follow-up PR.
|
|
31
|
+
-->
|
|
32
|
+
|
|
33
|
+
## Checklist
|
|
34
|
+
|
|
35
|
+
- [ ] `CHANGELOG.md` entry added under `[Unreleased]`.
|
|
36
|
+
- [ ] Tests added or updated under `test/`.
|
|
37
|
+
- [ ] Docs updated under `docs/` (and the relevant `docs/v1/*.md` checkbox
|
|
38
|
+
flipped if a roadmap item is closing).
|
|
39
|
+
- [ ] `bundle exec rake ci` is green locally.
|
data/.github/dependabot.yml
CHANGED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: CI
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main]
|
|
9
|
+
|
|
10
|
+
# Default to least privilege; jobs may opt into more.
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
test:
|
|
16
|
+
name: Minitest (Ruby ${{ matrix.ruby }})
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
strategy:
|
|
19
|
+
fail-fast: false
|
|
20
|
+
matrix:
|
|
21
|
+
ruby: ['3.4', '4.0']
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: ruby/setup-ruby@v1
|
|
25
|
+
with:
|
|
26
|
+
ruby-version: ${{ matrix.ruby }}
|
|
27
|
+
bundler-cache: true
|
|
28
|
+
- name: Run tests
|
|
29
|
+
run: bundle exec rake test
|
|
30
|
+
|
|
31
|
+
rubocop:
|
|
32
|
+
name: RuboCop
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
- uses: ruby/setup-ruby@v1
|
|
37
|
+
with:
|
|
38
|
+
ruby-version: '4.0'
|
|
39
|
+
bundler-cache: true
|
|
40
|
+
- name: Run RuboCop
|
|
41
|
+
run: bundle exec rubocop --parallel
|
|
42
|
+
|
|
43
|
+
steep:
|
|
44
|
+
name: Steep
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v4
|
|
48
|
+
- uses: ruby/setup-ruby@v1
|
|
49
|
+
with:
|
|
50
|
+
ruby-version: '3.4'
|
|
51
|
+
bundler-cache: true
|
|
52
|
+
- name: Run Steep
|
|
53
|
+
run: bundle exec steep check --jobs=1
|
|
54
|
+
|
|
55
|
+
coverage:
|
|
56
|
+
name: Coverage (SimpleCov)
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
- uses: ruby/setup-ruby@v1
|
|
61
|
+
with:
|
|
62
|
+
ruby-version: '4.0'
|
|
63
|
+
bundler-cache: true
|
|
64
|
+
- name: Run tests with SimpleCov
|
|
65
|
+
run: bundle exec rake test
|
|
66
|
+
- name: Append coverage summary
|
|
67
|
+
if: always()
|
|
68
|
+
run: |
|
|
69
|
+
ruby -rjson -e '
|
|
70
|
+
path = "coverage/.last_run.json"
|
|
71
|
+
unless File.exist?(path)
|
|
72
|
+
warn "no coverage/.last_run.json produced"
|
|
73
|
+
exit 0
|
|
74
|
+
end
|
|
75
|
+
data = JSON.parse(File.read(path))
|
|
76
|
+
line = data.dig("result", "line")
|
|
77
|
+
branch = data.dig("result", "branch")
|
|
78
|
+
File.open(ENV.fetch("GITHUB_STEP_SUMMARY"), "a") do |f|
|
|
79
|
+
f.puts "## SimpleCov coverage"
|
|
80
|
+
f.puts
|
|
81
|
+
f.puts "| Metric | Coverage | Soft target |"
|
|
82
|
+
f.puts "| ------ | -------- | ----------- |"
|
|
83
|
+
f.puts "| Line | #{line}% | >= 98% |"
|
|
84
|
+
f.puts "| Branch | #{branch}% | >= 95% |"
|
|
85
|
+
f.puts
|
|
86
|
+
f.puts "Reported only; not enforced in CI. See docs/v1/05-quality-and-tooling.md."
|
|
87
|
+
end
|
|
88
|
+
'
|
|
89
|
+
- name: Upload coverage HTML artifact
|
|
90
|
+
if: always()
|
|
91
|
+
uses: actions/upload-artifact@v7
|
|
92
|
+
with:
|
|
93
|
+
name: coverage-html
|
|
94
|
+
path: coverage/
|
|
95
|
+
if-no-files-found: warn
|
|
96
|
+
|
|
97
|
+
runtime-deps:
|
|
98
|
+
name: Runtime deps assertion (zero)
|
|
99
|
+
runs-on: ubuntu-latest
|
|
100
|
+
steps:
|
|
101
|
+
- uses: actions/checkout@v4
|
|
102
|
+
- uses: ruby/setup-ruby@v1
|
|
103
|
+
with:
|
|
104
|
+
ruby-version: '3.4'
|
|
105
|
+
- name: Assert assistant.gemspec declares zero runtime dependencies
|
|
106
|
+
run: |
|
|
107
|
+
ruby -e '
|
|
108
|
+
spec = Gem::Specification.load("assistant.gemspec")
|
|
109
|
+
deps = spec.runtime_dependencies.map(&:name)
|
|
110
|
+
if deps.empty?
|
|
111
|
+
puts "OK: assistant has zero runtime dependencies."
|
|
112
|
+
else
|
|
113
|
+
warn "FAIL: unexpected runtime dependencies: #{deps.join(", ")}"
|
|
114
|
+
exit 1
|
|
115
|
+
end
|
|
116
|
+
'
|
|
117
|
+
|
|
118
|
+
bin-smoke:
|
|
119
|
+
name: bin/ scripts smoke
|
|
120
|
+
runs-on: ubuntu-latest
|
|
121
|
+
steps:
|
|
122
|
+
- uses: actions/checkout@v4
|
|
123
|
+
- uses: ruby/setup-ruby@v1
|
|
124
|
+
with:
|
|
125
|
+
ruby-version: '3.4'
|
|
126
|
+
# Intentionally no bundler-cache: bin/setup is the thing under
|
|
127
|
+
# test; we want it to drive the bundle install end-to-end on a
|
|
128
|
+
# cold checkout.
|
|
129
|
+
- name: bin/setup smoke (cold bundle install)
|
|
130
|
+
run: ./bin/setup
|
|
131
|
+
- name: Syntax check bin/ scripts
|
|
132
|
+
run: |
|
|
133
|
+
bash -n bin/setup
|
|
134
|
+
ruby -c bin/console
|
|
135
|
+
ruby -c bin/version
|
|
136
|
+
- name: bin/version --help smoke
|
|
137
|
+
run: bundle exec bin/version --help
|
|
138
|
+
- name: bin/console loads assistant
|
|
139
|
+
run: |
|
|
140
|
+
echo 'puts Assistant::VERSION; exit' | bundle exec bin/console
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Docs
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
paths:
|
|
8
|
+
- docs/**
|
|
9
|
+
- _config.yml
|
|
10
|
+
- Gemfile
|
|
11
|
+
- Gemfile.lock
|
|
12
|
+
- .github/workflows/docs.yml
|
|
13
|
+
pull_request:
|
|
14
|
+
branches: [main]
|
|
15
|
+
paths:
|
|
16
|
+
- docs/**
|
|
17
|
+
- _config.yml
|
|
18
|
+
- Gemfile
|
|
19
|
+
- Gemfile.lock
|
|
20
|
+
- .github/workflows/docs.yml
|
|
21
|
+
workflow_dispatch:
|
|
22
|
+
|
|
23
|
+
permissions:
|
|
24
|
+
contents: read
|
|
25
|
+
|
|
26
|
+
concurrency:
|
|
27
|
+
group: pages
|
|
28
|
+
cancel-in-progress: false
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
build:
|
|
32
|
+
name: jekyll build --strict_front_matter
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
env:
|
|
35
|
+
BUNDLE_WITH: docs
|
|
36
|
+
JEKYLL_ENV: production
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
- uses: ruby/setup-ruby@v1
|
|
40
|
+
with:
|
|
41
|
+
ruby-version: '3.4'
|
|
42
|
+
bundler-cache: true
|
|
43
|
+
- name: Build site
|
|
44
|
+
run: bundle exec jekyll build --strict_front_matter --baseurl "/assistant"
|
|
45
|
+
- name: Upload site artifact
|
|
46
|
+
uses: actions/upload-pages-artifact@v3
|
|
47
|
+
with:
|
|
48
|
+
path: _site
|
|
49
|
+
|
|
50
|
+
deploy:
|
|
51
|
+
name: Deploy to GitHub Pages
|
|
52
|
+
needs: build
|
|
53
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
permissions:
|
|
56
|
+
pages: write
|
|
57
|
+
id-token: write
|
|
58
|
+
environment:
|
|
59
|
+
name: github-pages
|
|
60
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
61
|
+
steps:
|
|
62
|
+
- name: Deploy
|
|
63
|
+
id: deployment
|
|
64
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Release
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
tags:
|
|
7
|
+
- 'v*.*.*'
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
# Default to least privilege; the release job opts into the perms it needs.
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
release:
|
|
16
|
+
name: Build and publish gem
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
environment: rubygems
|
|
19
|
+
permissions:
|
|
20
|
+
contents: write
|
|
21
|
+
id-token: write
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: ruby/setup-ruby@v1
|
|
25
|
+
with:
|
|
26
|
+
ruby-version: '4.0'
|
|
27
|
+
bundler-cache: true
|
|
28
|
+
|
|
29
|
+
- name: Run tests before publishing
|
|
30
|
+
run: bundle exec rake test
|
|
31
|
+
|
|
32
|
+
- name: Configure trusted publishing
|
|
33
|
+
uses: rubygems/configure-rubygems-credentials@v2.1.0
|
|
34
|
+
|
|
35
|
+
- name: Build gem
|
|
36
|
+
run: gem build assistant.gemspec
|
|
37
|
+
|
|
38
|
+
- name: Push gem to RubyGems
|
|
39
|
+
run: gem push assistant-*.gem
|
|
40
|
+
|
|
41
|
+
- name: Create GitHub Release
|
|
42
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
43
|
+
uses: softprops/action-gh-release@v2
|
|
44
|
+
with:
|
|
45
|
+
generate_release_notes: true
|
|
46
|
+
files: assistant-*.gem
|
data/.gitignore
CHANGED
data/.markdownlint.json
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: create-pr
|
|
3
|
+
description: Use when opening a GitHub pull request for the assistant gem (e.g. `gh pr create`, "open a PR", "ship this branch"). Ensures local checks pass, only intended files are committed, commit/PR follow the M<num> convention, and the PR is assigned to the GitHub user before returning the URL.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: create-pr
|
|
7
|
+
|
|
8
|
+
PRs for this repo follow a strict shape. Walk through every step in order.
|
|
9
|
+
Skipping any one of them is a defect.
|
|
10
|
+
|
|
11
|
+
## 1. Verify local checks before pushing
|
|
12
|
+
|
|
13
|
+
Run all three from the worktree root and confirm each is green. None of these
|
|
14
|
+
should be skipped because "the change is small" — the CI gate will reject the
|
|
15
|
+
PR anyway.
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
bundle exec rake test
|
|
19
|
+
bundle exec rubocop
|
|
20
|
+
bundle exec steep check --jobs=1
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
If anything fails, fix it on the branch (or revert the offending hunk) before
|
|
24
|
+
committing. Do not commit "WIP" or "fix in CI" placeholders.
|
|
25
|
+
|
|
26
|
+
## 2. Stage only the intended files
|
|
27
|
+
|
|
28
|
+
Inspect `git status --short` before staging. Explicitly enumerate paths to
|
|
29
|
+
`git add` — never run `git add .` or `git add -A`.
|
|
30
|
+
|
|
31
|
+
**Always exclude** the following even if they appear as untracked or modified:
|
|
32
|
+
|
|
33
|
+
- Anything under `.opencode/` **except** committed config (`.opencode/.gitignore`,
|
|
34
|
+
`.opencode/opencode.json`) and project-owned skills under
|
|
35
|
+
`.opencode/skills/<name>/`. Transient agent state, scratch files, and
|
|
36
|
+
unrelated skills (e.g. `.opencode/skills/ruby-services/` if not owned by
|
|
37
|
+
this project) stay untracked.
|
|
38
|
+
- `.DS_Store`, `*.swp`, `*~`, any local-only debug scripts
|
|
39
|
+
- `Gemfile.lock` is fine to commit when an actual dep changed; do not stage it
|
|
40
|
+
for unrelated mechanical updates
|
|
41
|
+
|
|
42
|
+
If something unrelated was modified during exploration (e.g. accidental
|
|
43
|
+
reformat of an untouched file), restore it with `git restore <path>` first.
|
|
44
|
+
|
|
45
|
+
After staging, re-check with `git diff --cached --stat` and confirm the file
|
|
46
|
+
list matches the PR's scope.
|
|
47
|
+
|
|
48
|
+
## 3. Commit message convention
|
|
49
|
+
|
|
50
|
+
The repo's commit messages follow:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
<TAG>: <short imperative summary, <=72 chars>
|
|
54
|
+
|
|
55
|
+
<wrapped body explaining the WHAT and WHY, not the HOW>
|
|
56
|
+
<reference roadmap milestones or issues by ID>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`<TAG>` is one of:
|
|
60
|
+
|
|
61
|
+
- `M<n>` — a v1 roadmap milestone (e.g. `M11: bin/assistant-rbs per-class
|
|
62
|
+
RBS generator`). Look up the number in `docs/v1/02-features.md`.
|
|
63
|
+
- `M-S<n>` — a "stretch" / promoted roadmap item.
|
|
64
|
+
- `D<n>` — a documentation milestone from `docs/v1/04-documentation.md`.
|
|
65
|
+
- A short topic tag like `chore:`, `docs:`, `refactor:` when the change does
|
|
66
|
+
not map to a roadmap item.
|
|
67
|
+
|
|
68
|
+
The body wraps at ~72 cols and explains the WHY. Do not paste tool output or
|
|
69
|
+
file lists — the diff already shows that.
|
|
70
|
+
|
|
71
|
+
Pre-commit hooks may reject the commit. If they do, fix the issue and create
|
|
72
|
+
a **new** commit. Do not `--amend` past hook failures.
|
|
73
|
+
|
|
74
|
+
## 4. Push and track
|
|
75
|
+
|
|
76
|
+
```sh
|
|
77
|
+
git push -u origin <branch>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The branch name should already match the work: `feature/m<n>-<slug>` for
|
|
81
|
+
roadmap milestones, or `<topic>/<slug>` otherwise.
|
|
82
|
+
|
|
83
|
+
## 5. Open the PR
|
|
84
|
+
|
|
85
|
+
Use `gh pr create` with `--base main`, the explicit `--head <branch>`, a
|
|
86
|
+
`--title` that mirrors the lead commit's subject, and a `--body` that covers:
|
|
87
|
+
|
|
88
|
+
- **Scope** — what milestone / issue this implements (link the roadmap line).
|
|
89
|
+
- **What this PR ships** — bullet list of the public-facing changes.
|
|
90
|
+
- **Sample output / behavior** — fenced block when the change has a visible
|
|
91
|
+
surface (CLI output, generated artifact, error message).
|
|
92
|
+
- **Verification** — the green output of `rake test`, `rubocop`, and
|
|
93
|
+
`steep check`. Paste the actual tail of each command.
|
|
94
|
+
- **Out of scope** — what was deliberately left for later (e.g. "M12 changes
|
|
95
|
+
this DSL signature; that ships in its own PR").
|
|
96
|
+
|
|
97
|
+
Pass the body via a heredoc so newlines and quoting survive:
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
gh pr create --base main --head <branch> --title "..." --body "$(cat <<'EOF'
|
|
101
|
+
...
|
|
102
|
+
EOF
|
|
103
|
+
)"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 6. Assign the PR
|
|
107
|
+
|
|
108
|
+
GitHub does not auto-assign. **Always** assign the PR to the authenticated
|
|
109
|
+
user immediately after creation:
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
gh pr edit <number> --add-assignee "$(gh api user --jq .login)"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Confirm the assignment landed by re-reading the PR URL output — `gh pr edit`
|
|
116
|
+
prints the URL on success.
|
|
117
|
+
|
|
118
|
+
## 7. Return the PR URL
|
|
119
|
+
|
|
120
|
+
The final message to the user must include the PR URL on its own line so the
|
|
121
|
+
terminal renders it as a clickable link. Mention the PR number, the commit
|
|
122
|
+
SHA(s) it contains, and the assignee.
|
|
123
|
+
|
|
124
|
+
## Common pitfalls
|
|
125
|
+
|
|
126
|
+
- **Committing transient `.opencode/` state** — agent scratch files and skills
|
|
127
|
+
that aren't owned by this repo must never appear in `git status` as staged.
|
|
128
|
+
Project-owned skills under `.opencode/skills/<name>/SKILL.md` are fine to
|
|
129
|
+
commit when they're part of the change.
|
|
130
|
+
- **Forgetting to push before `gh pr create`** — `gh` will error with
|
|
131
|
+
`pull request create failed: GraphQL: No commits between main and …`.
|
|
132
|
+
Always `git push -u origin <branch>` first.
|
|
133
|
+
- **Skipping the assignee step** — unassigned PRs get lost in the review
|
|
134
|
+
queue. Always run step 6.
|
|
135
|
+
- **Empty `--body`** — `gh pr create` will silently use the commit message as
|
|
136
|
+
the body, which usually under-documents the change. Always pass `--body`.
|
|
137
|
+
- **`--amend` after a pre-commit hook failure** — the failure already left
|
|
138
|
+
artifacts in the index; create a fresh commit instead.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ruby-services
|
|
3
|
+
description: Use when creating, changing, testing, or reviewing Ruby service objects, especially Assistant::Service subclasses, service inputs, validation, execution, logs, or Minitest coverage.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Ruby Services
|
|
7
|
+
|
|
8
|
+
Use this skill when working on Ruby service objects in this repository,
|
|
9
|
+
especially `Assistant::Service` subclasses or framework behavior that affects
|
|
10
|
+
service inputs, validation, execution, logs, result hashes, or tests.
|
|
11
|
+
|
|
12
|
+
Do not use this skill for unrelated Ruby scripts, packaging-only changes, or
|
|
13
|
+
opencode configuration tasks unless the work directly concerns Ruby service
|
|
14
|
+
guidance.
|
|
15
|
+
|
|
16
|
+
## Core Approach
|
|
17
|
+
|
|
18
|
+
- Preserve the existing `Assistant::Service` public API unless the user asks for
|
|
19
|
+
an API change.
|
|
20
|
+
- Prefer soft-fail service behavior: report domain and validation failures with
|
|
21
|
+
error logs instead of raising, unless an exception is explicitly part of the
|
|
22
|
+
API being changed.
|
|
23
|
+
- Keep service logic clear and object-oriented: every method should have one
|
|
24
|
+
responsibility.
|
|
25
|
+
- Only add a private helper when it makes sense in the context of the service's
|
|
26
|
+
domain and improves readability.
|
|
27
|
+
- Keep helper names aligned with what the service does, not generic process
|
|
28
|
+
steps like `handle_data` or `process_stuff`.
|
|
29
|
+
- Do not add arguments to service instance methods other than `initialize`.
|
|
30
|
+
Service behavior should use declared inputs and instance state.
|
|
31
|
+
- Return computed data from `execute`; put pre-execution domain checks in
|
|
32
|
+
`validate`.
|
|
33
|
+
- Use `log_item_warning`, `log_item_error`, `log_item_info`, or
|
|
34
|
+
`add_log(level:, source:, detail:, message:)` consistently with existing
|
|
35
|
+
log patterns.
|
|
36
|
+
|
|
37
|
+
## Inputs
|
|
38
|
+
|
|
39
|
+
- Declare service inputs with `input :name, type: SomeClass` and existing DSL
|
|
40
|
+
options such as `required:`, `optional:`, `default:`, `allow_nil:`, and `if:`.
|
|
41
|
+
- Prefer `default: -> { [] }` or `default: -> { {} }` for mutable defaults.
|
|
42
|
+
- Use `allow_nil: true` only when explicit `nil` is a valid service value.
|
|
43
|
+
- Do not depend on deprecated `valid_require_*?` names in new internal code;
|
|
44
|
+
use the canonical `valid_required_*?` names.
|
|
45
|
+
|
|
46
|
+
## Tests
|
|
47
|
+
|
|
48
|
+
- Add or update Minitest coverage under `test/**/*_test.rb` for behavior
|
|
49
|
+
changes.
|
|
50
|
+
- Use anonymous `Class.new(Assistant::Service)` fixtures for framework-level
|
|
51
|
+
service behavior, matching the existing tests.
|
|
52
|
+
- Assert the service result hash shape, `status`, `warnings`, `errors`, logs,
|
|
53
|
+
and memoization when relevant.
|
|
54
|
+
- For input DSL changes, cover required, optional, default, type, conditional,
|
|
55
|
+
and `allow_nil` behavior as applicable.
|
|
56
|
+
- Use helpers from `test/test_helper.rb` for log-item construction or warning
|
|
57
|
+
capture instead of duplicating helper setup.
|
|
58
|
+
|
|
59
|
+
## Style
|
|
60
|
+
|
|
61
|
+
- Ruby target is 3.4.
|
|
62
|
+
- Start Ruby files with `# frozen_string_literal: true`.
|
|
63
|
+
- Prefer concise Ruby that matches nearby code; endless methods are acceptable
|
|
64
|
+
where they are already used.
|
|
65
|
+
- Respect the repo's hybrid compact nesting convention from
|
|
66
|
+
`rubocop-style-compact_nesting`.
|
|
67
|
+
- Keep public API documentation aligned with `docs/v1/01-api-surface.md` and
|
|
68
|
+
user-facing changes aligned with `CHANGELOG.md` when appropriate.
|
|
69
|
+
- Make the smallest correct change; avoid generic abstractions until there is a
|
|
70
|
+
concrete second use.
|
|
71
|
+
|
|
72
|
+
## Verification
|
|
73
|
+
|
|
74
|
+
Run the focused test first when possible, then the broader checks relevant to
|
|
75
|
+
the change:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
bundle exec ruby -Itest test/assistant/service_test.rb
|
|
79
|
+
bundle exec rake test
|
|
80
|
+
bundle exec rubocop
|
|
81
|
+
```
|