reclaim 0.2.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2542e7a0ad06c9e9fef776da44dade129f247eefd519a32705168ef6d678b8bb
4
+ data.tar.gz: b51a8d23c1ce024d30ef4f0390ffdf8603ebb39061b1a6d61b97143300ea1360
5
+ SHA512:
6
+ metadata.gz: 408a148e25073ed4e6735d6517df1dc2a79c164080489f4d951e43169afa2d5f581d5292b9acbfa624eaeedad5fe7a6517fd5e0dc04a06aba58944303adf7e8b
7
+ data.tar.gz: d52a5412e0830c622d1c5b53a38f7d289e286f51b78230458f88ff1574983bcb62fa5b1d090d3540a3d193799855a9ec5a0072e91e310f9b5d5ebd868ffe2bd4
data/CHANGELOG.md ADDED
@@ -0,0 +1,46 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.2.0] - 2025-11-14
11
+
12
+ ### Added
13
+ - Dotenv support for environment variable management
14
+ - Automatic loading of `.env` files for API token configuration
15
+ - Development dependency on `dotenv` gem (~> 2.8)
16
+
17
+ ### Changed
18
+ - Renamed environment variable from `RECLAIM_TOKEN` to `RECLAIM_API_KEY` for clarity
19
+
20
+ ## [0.1.0] - 2025-10-29
21
+
22
+ ### Added
23
+ - Initial release of Reclaim Ruby client
24
+ - Complete task management API (CRUD operations)
25
+ - Task filtering by status (active, completed, overdue)
26
+ - Time scheme support with fuzzy name matching
27
+ - Task splitting control (prevent splitting or configure chunk sizes)
28
+ - Priority levels (P1-P4)
29
+ - Date management (due dates, defer dates, start times)
30
+ - Comprehensive error handling with custom exception types
31
+ - Command-line interface (`reclaim` executable)
32
+ - CLI commands: list, create, get, update, complete, delete, list-schemes
33
+ - Full test suite (unit tests + integration tests)
34
+ - Zero runtime dependencies (stdlib only)
35
+ - Ruby 3.0+ support
36
+
37
+ ### Features
38
+ - **Client**: HTTP client with authentication and caching
39
+ - **Task Model**: Task representation with status helpers
40
+ - **Utils**: Formatting and parsing utilities
41
+ - **CLI**: Full-featured command-line interface
42
+ - **Errors**: Custom exception hierarchy for better error handling
43
+
44
+ [Unreleased]: https://github.com/benjaminjackson/reclaim-ruby/compare/v0.2.0...HEAD
45
+ [0.2.0]: https://github.com/benjaminjackson/reclaim-ruby/compare/v0.1.0...v0.2.0
46
+ [0.1.0]: https://github.com/benjaminjackson/reclaim-ruby/releases/tag/v0.1.0
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Benjamin Jackson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,367 @@
1
+ # Reclaim Ruby Client
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/reclaim.svg)](https://badge.fury.io/rb/reclaim)
4
+ [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.0.0-ruby.svg)](https://www.ruby-lang.org/)
5
+
6
+ A comprehensive Ruby library for interacting with the [Reclaim.ai](https://reclaim.ai) API. Manage your tasks programmatically with proper error handling, time scheme resolution, caching, and a powerful command-line interface.
7
+
8
+ ## Features
9
+
10
+ - **Complete Task Management**: Create, read, update, delete, and complete tasks
11
+ - **Time Scheme Support**: Resolve time schemes by name with fuzzy matching
12
+ - **Task Filtering**: Filter tasks by status (active, completed, overdue)
13
+ - **Flexible Scheduling**: Control task splitting, chunk sizes, and defer dates
14
+ - **CLI Tool**: Full-featured command-line interface for task management
15
+ - **Error Handling**: Comprehensive exception handling with custom error types
16
+ - **Zero Dependencies**: Uses only Ruby stdlib (no runtime dependencies)
17
+ - **Well Tested**: Extensive test coverage with unit and integration tests
18
+
19
+ ## Installation
20
+
21
+ Install the gem:
22
+
23
+ ```bash
24
+ gem install reclaim
25
+ ```
26
+
27
+ Or add to your Gemfile:
28
+
29
+ ```ruby
30
+ gem 'reclaim'
31
+ ```
32
+
33
+ ## Configuration
34
+
35
+ Set your Reclaim.ai API token as an environment variable:
36
+
37
+ ```bash
38
+ export RECLAIM_API_KEY='your_api_token_here'
39
+ ```
40
+
41
+ Get your API token from your [Reclaim.ai settings](https://app.reclaim.ai/settings/developer).
42
+
43
+ ### Using .env Files (Optional)
44
+
45
+ If you have the `dotenv` gem installed, the library will automatically load environment variables from `.env` and `.env.local` files from your current working directory. This is helpful for local development:
46
+
47
+ ```bash
48
+ # .env
49
+ RECLAIM_API_KEY='your_api_token_here'
50
+ ```
51
+
52
+ **For users of this gem**: If you're using reclaim-ruby as a library in your own project and want .env file support, add dotenv to your project's Gemfile:
53
+
54
+ ```ruby
55
+ gem 'dotenv', '~> 2.8'
56
+ ```
57
+
58
+ **For contributors**: dotenv is already included as a development dependency for working on this gem.
59
+
60
+ **File precedence**: `.env.local` takes precedence over `.env` and is typically gitignored for local-only overrides. Environment variables already set in your shell take precedence over .env files.
61
+
62
+ ## Usage
63
+
64
+ ### Ruby Library
65
+
66
+ ```ruby
67
+ require 'reclaim'
68
+
69
+ # Initialize client (uses ENV['RECLAIM_API_KEY'] by default)
70
+ client = Reclaim::Client.new
71
+
72
+ # Or pass token explicitly
73
+ client = Reclaim::Client.new('your_api_token')
74
+
75
+ # Create a task
76
+ task = client.create_task(
77
+ title: 'Important Work',
78
+ due_date: '2025-12-31T17:00:00Z',
79
+ priority: :p1,
80
+ duration: 2.0, # hours
81
+ notes: 'This is important!',
82
+ time_scheme: 'work'
83
+ )
84
+
85
+ puts "Created task: #{task.title} (#{task.id})"
86
+
87
+ # List tasks
88
+ active_tasks = client.list_tasks(filter: :active)
89
+ completed_tasks = client.list_tasks(filter: :completed)
90
+ overdue_tasks = client.list_tasks(filter: :overdue)
91
+ all_tasks = client.list_tasks # No filter
92
+
93
+ active_tasks.each do |task|
94
+ puts "#{task.title} - #{task.status} (Priority: #{task.priority})"
95
+ end
96
+
97
+ # Get a specific task
98
+ task = client.get_task('task_id_here')
99
+
100
+ # Update a task
101
+ updated_task = client.update_task(
102
+ task.id,
103
+ title: 'Updated Title',
104
+ priority: :p2,
105
+ duration: 3.0
106
+ )
107
+
108
+ # Mark task as complete (archives it)
109
+ completed_task = client.complete_task(task.id)
110
+
111
+ # Delete a task
112
+ client.delete_task(task.id)
113
+
114
+ # List available time schemes
115
+ schemes = client.list_time_schemes
116
+ schemes.each do |scheme|
117
+ puts "#{scheme['title']} (#{scheme['id']})"
118
+ end
119
+
120
+ # Get formatted time schemes
121
+ puts client.format_time_schemes
122
+ ```
123
+
124
+ ### Task Priorities
125
+
126
+ Tasks support four priority levels:
127
+
128
+ - `:p1` - Highest priority (P1)
129
+ - `:p2` - High priority (P2)
130
+ - `:p3` - Normal priority (P3, default)
131
+ - `:p4` - Low priority (P4)
132
+
133
+ ### Task Splitting
134
+
135
+ Control whether tasks can be split into smaller chunks:
136
+
137
+ ```ruby
138
+ # Prevent splitting (default)
139
+ task = client.create_task(
140
+ title: 'Deep Work Session',
141
+ duration: 4.0 # Must be scheduled as a single 4-hour block
142
+ )
143
+
144
+ # Allow splitting with default chunk sizes
145
+ task = client.create_task(
146
+ title: 'Flexible Task',
147
+ duration: 3.0,
148
+ allow_splitting: true # Can be split into 15min-3hr chunks
149
+ )
150
+
151
+ # Allow splitting with custom minimum chunk size
152
+ task = client.create_task(
153
+ title: 'Research',
154
+ duration: 4.0,
155
+ allow_splitting: true,
156
+ split_chunk_size: 0.5 # Minimum 30-minute chunks
157
+ )
158
+
159
+ # Full control over chunk sizes
160
+ task = client.create_task(
161
+ title: 'Writing',
162
+ duration: 6.0,
163
+ allow_splitting: true,
164
+ min_chunk_size: 1.0, # Minimum 1 hour
165
+ max_chunk_size: 2.0 # Maximum 2 hours
166
+ )
167
+ ```
168
+
169
+ ### Time Schemes
170
+
171
+ Time schemes control when tasks can be scheduled. You can reference them by name:
172
+
173
+ ```ruby
174
+ # Use exact name
175
+ task = client.create_task(
176
+ title: 'Work Task',
177
+ time_scheme: 'Work Hours'
178
+ )
179
+
180
+ # Use alias (fuzzy matching)
181
+ task = client.create_task(
182
+ title: 'Work Task',
183
+ time_scheme: 'work' # Finds "Work Hours"
184
+ )
185
+
186
+ # Supported aliases:
187
+ # - 'work', 'working hours', 'business hours' → finds schemes with 'work'
188
+ # - 'personal', 'off hours', 'private' → finds schemes with 'personal'
189
+ ```
190
+
191
+ ### Error Handling
192
+
193
+ The library provides specific exception types:
194
+
195
+ ```ruby
196
+ begin
197
+ client = Reclaim::Client.new('invalid_token')
198
+ rescue Reclaim::AuthenticationError => e
199
+ puts "Authentication failed: #{e.message}"
200
+ end
201
+
202
+ begin
203
+ task = client.get_task('nonexistent_id')
204
+ rescue Reclaim::NotFoundError => e
205
+ puts "Task not found: #{e.message}"
206
+ end
207
+
208
+ begin
209
+ task = client.create_task(title: '', time_scheme: 'invalid')
210
+ rescue Reclaim::InvalidRecordError => e
211
+ puts "Validation error: #{e.message}"
212
+ end
213
+
214
+ begin
215
+ # Network or API errors
216
+ tasks = client.list_tasks
217
+ rescue Reclaim::ApiError => e
218
+ puts "API error: #{e.message}"
219
+ puts "Status: #{e.status_code}" if e.status_code
220
+ end
221
+ ```
222
+
223
+ ### Command-Line Interface
224
+
225
+ The gem includes a full-featured CLI:
226
+
227
+ ```bash
228
+ # List active tasks (default)
229
+ reclaim
230
+ reclaim list active
231
+
232
+ # List completed or overdue tasks
233
+ reclaim list completed
234
+ reclaim list overdue
235
+
236
+ # Create a task
237
+ reclaim create --title "Important Meeting Prep" \
238
+ --due 2025-12-31 \
239
+ --priority P1 \
240
+ --duration 2
241
+
242
+ # Create a task that allows splitting
243
+ reclaim create --title "Research Project" \
244
+ --duration 4 \
245
+ --split 0.5 # 30-minute minimum chunks
246
+
247
+ # Get task details
248
+ reclaim get TASK_ID
249
+
250
+ # Update a task
251
+ reclaim update TASK_ID \
252
+ --title "Updated Title" \
253
+ --priority P2
254
+
255
+ # Clear a date field
256
+ reclaim update TASK_ID --due none
257
+ reclaim update TASK_ID --defer clear
258
+
259
+ # Mark task as complete
260
+ reclaim complete TASK_ID
261
+
262
+ # Delete a task
263
+ reclaim delete TASK_ID
264
+
265
+ # List available time schemes
266
+ reclaim list-schemes
267
+
268
+ # Get help
269
+ reclaim help
270
+ reclaim --help
271
+ ```
272
+
273
+ ## Development
274
+
275
+ ### Setup
276
+
277
+ ```bash
278
+ git clone https://github.com/benjaminjackson/reclaim-ruby.git
279
+ cd reclaim-ruby
280
+ bundle install
281
+ ```
282
+
283
+ ### Running Tests
284
+
285
+ ```bash
286
+ # Run unit tests only (no API calls)
287
+ SKIP_INTEGRATION_TESTS=true bundle exec rake test
288
+
289
+ # Run all tests (requires RECLAIM_API_KEY)
290
+ bundle exec rake test
291
+
292
+ # Run only integration tests
293
+ bundle exec rake test TESTOPTS='-n /Integration/'
294
+ ```
295
+
296
+ ### Building the Gem
297
+
298
+ ```bash
299
+ gem build reclaim.gemspec
300
+ gem install ./reclaim-0.1.0.gem
301
+ ```
302
+
303
+ ## API Reference
304
+
305
+ ### Reclaim::Client
306
+
307
+ Main client for API interactions.
308
+
309
+ **Methods:**
310
+
311
+ - `initialize(token = nil)` - Create client (uses ENV['RECLAIM_API_KEY'] if token not provided)
312
+ - `create_task(**options)` - Create a new task
313
+ - `list_tasks(filter: nil)` - List all tasks (filter: :active, :completed, :overdue, or nil)
314
+ - `get_task(task_id)` - Get a specific task by ID
315
+ - `update_task(task_id, **options)` - Update an existing task
316
+ - `complete_task(task_id)` - Mark task as complete (ARCHIVED status)
317
+ - `delete_task(task_id)` - Permanently delete a task
318
+ - `list_time_schemes` - Get available time schemes
319
+ - `format_time_schemes` - Get formatted time schemes for display
320
+
321
+ ### Reclaim::Task
322
+
323
+ Task model with properties and helper methods.
324
+
325
+ **Properties:**
326
+
327
+ - `id`, `title`, `notes`, `due_date`, `priority`, `duration`
328
+ - `status`, `time_scheme_id`, `always_private`, `event_category`, `event_color`
329
+ - `min_chunk_size`, `max_chunk_size`, `snooze_until`, `start`
330
+
331
+ **Methods:**
332
+
333
+ - `active?` - Check if task is active (not deleted/archived/cancelled)
334
+ - `completed?` - Check if task is completed (COMPLETE or ARCHIVED status)
335
+ - `overdue?` - Check if task is past its due date
336
+ - `due_date_formatted` - Get formatted due date string
337
+ - `priority_symbol` - Get priority as symbol (:p1, :p2, :p3, :p4)
338
+
339
+ ### Exception Classes
340
+
341
+ - `Reclaim::Error` - Base exception class
342
+ - `Reclaim::AuthenticationError` - Authentication/token errors
343
+ - `Reclaim::ApiError` - API/network errors (includes status_code and response_body)
344
+ - `Reclaim::NotFoundError` - Resource not found (404)
345
+ - `Reclaim::InvalidRecordError` - Validation errors (422)
346
+
347
+ ## Contributing
348
+
349
+ Bug reports and pull requests are welcome on GitHub at https://github.com/benjaminjackson/reclaim-ruby.
350
+
351
+ 1. Fork it
352
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
353
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
354
+ 4. Push to the branch (`git push origin my-new-feature`)
355
+ 5. Create new Pull Request
356
+
357
+ ## License
358
+
359
+ The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
360
+
361
+ ## Links
362
+
363
+ - **RubyGems**: https://rubygems.org/gems/reclaim
364
+ - **Source Code**: https://github.com/benjaminjackson/reclaim-ruby
365
+ - **Bug Reports**: https://github.com/benjaminjackson/reclaim-ruby/issues
366
+ - **Reclaim.ai**: https://reclaim.ai
367
+ - **API Documentation**: https://reclaim.ai/api
data/bin/reclaim ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'reclaim'
5
+
6
+ Reclaim::CLI.run