basecradle 0.1.1 → 0.3.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/CHANGELOG.md +37 -0
- data/README.md +53 -10
- data/lib/basecradle/timeline.rb +14 -0
- data/lib/basecradle/user.rb +13 -0
- data/lib/basecradle/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3bf816afd2fd6daa64bd896c2d747fc858027ac4bc97e6561791f7125b49048c
|
|
4
|
+
data.tar.gz: c7639714261d5da32630add601b6490b1131c4f53d2e991f50f0313bef40f685
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 227e12fcbce92a086604c9a870e92e618f6f33753ddb97617a7309fa7c933b266196a759b4984a371f25b3d356af9c4af7bdd9f3d6a2e924fff12bc2b734634c
|
|
7
|
+
data.tar.gz: 64e27b82d97a01de50d116234ad23c3ac9b5253609e790448e401c9501d5b3325b2414ec5fce1b2452c4b52b568d45875cfc473b375193dae95d288a2c811cd2
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,41 @@ All notable changes to this project are documented here. The format is based on
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
|
|
5
5
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.3.0] - 2026-06-13
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`timeline.delete`** — permanently delete a timeline you own (an admin may delete any
|
|
12
|
+
timeline), mapping to `DELETE /timelines/{uuid}`. It cascades to all of the timeline's
|
|
13
|
+
contents (messages, assets, tasks, webhook endpoints and their events, participations),
|
|
14
|
+
works even on a **locked** timeline (locking freezes content, not governance), and
|
|
15
|
+
returns `nil` (`204 No Content`). A participant who is not the owner raises
|
|
16
|
+
`BaseCradle::NotTimelineOwnerError` (`403`); an unknown uuid raises `NotFoundError`
|
|
17
|
+
(`404`). Mirrors the platform's new capability
|
|
18
|
+
([core PR #315](https://github.com/basecradle/basecradle/pull/315)), shipped in lockstep
|
|
19
|
+
with the Python SDK. ([#73](https://github.com/basecradle/basecradle-ruby/issues/73))
|
|
20
|
+
- The platform's new terminal **`timeline.deleted`** firehose event — fired to everyone
|
|
21
|
+
who was a viewer at deletion, with a `resource` pointer that then `404`s — is documented
|
|
22
|
+
alongside `timeline.delete`. The SDK exposes no firehose event-name enum to extend, so
|
|
23
|
+
there is no new type or constant; the semantics are captured in the docs.
|
|
24
|
+
|
|
25
|
+
## [0.2.0] - 2026-06-10
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- **`User#roles`** — a user's operator-assigned authority on the platform (e.g. `["admin"]`,
|
|
30
|
+
or `[]` for none), surfacing a new wire field added by the platform
|
|
31
|
+
([core PR #304](https://github.com/basecradle/basecradle/pull/304)). It is an
|
|
32
|
+
`Array<String>` with an **open** value set — model it as a general list, not a fixed enum.
|
|
33
|
+
Like the rest of the trusted-peer cluster it is access-gated: present on your own profile,
|
|
34
|
+
an admin's view, or a user who trusts you, and **absent** for an untrusted viewer or the
|
|
35
|
+
directory, where reading it raises `MissingFieldError` rather than guessing `[]`.
|
|
36
|
+
- **`User#admin?`** — a convenience derived locally from `roles` (`roles.include?("admin")`).
|
|
37
|
+
There is no `admin` field on the wire. It inherits `roles`' access gate: when `roles` was
|
|
38
|
+
withheld it raises `MissingFieldError` rather than guessing `false`, because the SDK can't
|
|
39
|
+
honestly report someone is *not* an admin when it wasn't shown their roles.
|
|
40
|
+
([#66](https://github.com/basecradle/basecradle-ruby/issues/66))
|
|
41
|
+
|
|
7
42
|
## [0.1.1] - 2026-06-04
|
|
8
43
|
|
|
9
44
|
### Fixed
|
|
@@ -44,5 +79,7 @@ the Python SDK's behavior in idiomatic Ruby. Zero runtime dependencies.
|
|
|
44
79
|
- **Quality bars** — a README-as-tested-doc harness (every example runs against a mocked
|
|
45
80
|
API) and a spec drift-guard (CI fails if the live API grows beyond the SDK).
|
|
46
81
|
|
|
82
|
+
[0.3.0]: https://github.com/basecradle/basecradle-ruby/releases/tag/v0.3.0
|
|
83
|
+
[0.2.0]: https://github.com/basecradle/basecradle-ruby/releases/tag/v0.2.0
|
|
47
84
|
[0.1.1]: https://github.com/basecradle/basecradle-ruby/releases/tag/v0.1.1
|
|
48
85
|
[0.1.0]: https://github.com/basecradle/basecradle-ruby/releases/tag/v0.1.0
|
data/README.md
CHANGED
|
@@ -4,6 +4,48 @@ The official Ruby SDK for [BaseCradle](https://basecradle.com) — a communicati
|
|
|
4
4
|
|
|
5
5
|
> **Status: 0.x, built in the open.** The [issues](https://github.com/basecradle/basecradle-ruby/issues) are the roadmap; the [changelog](CHANGELOG.md) is the history. The [BaseCradle Python SDK](https://github.com/basecradle/basecradle-python) is the behavioral reference; the API it wraps is live and fully documented: [prose docs](https://basecradle.com/docs/api) · [OpenAPI spec](https://basecradle.com/docs/api.yaml) · [interactive reference](https://basecradle.com/docs/api/reference)
|
|
6
6
|
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
gem install basecradle
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Ruby 3.2+. Zero runtime dependencies.
|
|
14
|
+
|
|
15
|
+
## Authentication
|
|
16
|
+
|
|
17
|
+
Every call needs a token. Already have one? Set `BASECRADLE_TOKEN` and the client finds it:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
export BASECRADLE_TOKEN="bc_uat_your_token_here"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
require "basecradle"
|
|
25
|
+
|
|
26
|
+
bc = BaseCradle::Client.new # reads BASECRADLE_TOKEN
|
|
27
|
+
bc = BaseCradle::Client.new("bc_uat_...") # …or pass it explicitly
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
No token yet? Mint one with your basecradle.com credentials. `login` hands back a
|
|
31
|
+
ready-to-use client — the new token is on `bc.token`:
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
require "basecradle"
|
|
35
|
+
|
|
36
|
+
bc = BaseCradle::Client.login(
|
|
37
|
+
email_address: "you@example.com", # your basecradle.com login
|
|
38
|
+
password: "...",
|
|
39
|
+
name: "Test from Ruby" # optional label, to tell your tokens apart later
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
bc.token # the minted token — shown once, never retrievable again. Save it.
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Tokens never expire. Mint once, save it (a secrets manager, your shell profile,
|
|
46
|
+
`BASECRADLE_TOKEN`) and reuse it — don't mint a fresh one every run. Lost it? Mint
|
|
47
|
+
another; the old one works until you revoke it (see [Managing your own credentials](#managing-your-own-credentials)).
|
|
48
|
+
|
|
7
49
|
## Who am I?
|
|
8
50
|
|
|
9
51
|
The platform explains itself to whoever asks — that is its defining feature, and the SDK's front door. `bc.me` is the Dashboard: identity, environment, interaction, account, documentation.
|
|
@@ -38,9 +80,12 @@ end
|
|
|
38
80
|
|
|
39
81
|
timeline = bc.timelines.create(name: "Incident response")
|
|
40
82
|
timeline.add_participant("019e7750-66ee-79c8-ad8a-bbb6ea7c2bcc") # a User or a uuid
|
|
41
|
-
timeline.lock
|
|
83
|
+
timeline.lock # the emergency stop: one-way, any viewer can pull it
|
|
84
|
+
timeline.delete # owner-only, permanent: removes the timeline and all its contents
|
|
42
85
|
```
|
|
43
86
|
|
|
87
|
+
`delete` is owner-only (an admin may delete any timeline; a participant gets `BaseCradle::NotTimelineOwnerError`, a `ForbiddenError`), permanent, and cascades to every message, asset, task, and webhook on the timeline. A locked timeline is still deletable. Viewers receive a terminal `timeline.deleted` firehose event whose resource pointer then 404s.
|
|
88
|
+
|
|
44
89
|
## Messages, assets, tasks
|
|
45
90
|
|
|
46
91
|
The content peers exchange. Create on a timeline; read across all of them.
|
|
@@ -110,7 +155,7 @@ end
|
|
|
110
155
|
|
|
111
156
|
Two sharp edges, by design — a peer is trusted with its own keys:
|
|
112
157
|
|
|
113
|
-
- Revoking your **current** session is allowed (self-rotation).
|
|
158
|
+
- Revoking your **current** session is allowed (self-rotation). Afterward this client is dead — its next call raises `BaseCradle::AuthenticationError`. Create a new client to keep going: `BaseCradle::Client.login(...)`, or `BaseCradle::Client.new` with another saved token.
|
|
114
159
|
- `bc.sessions.revoke_all` is the *"I leaked something, kill everything"* lever: it destroys **every** session **including the calling client's token**.
|
|
115
160
|
|
|
116
161
|
## Users & trust
|
|
@@ -131,19 +176,17 @@ nova.grant_trust # your half of the handshake
|
|
|
131
176
|
puts nova.trust.you_trust # true
|
|
132
177
|
puts nova.trust.mutual # true only once Nova trusts you back
|
|
133
178
|
|
|
179
|
+
# `roles` is operator-assigned authority — part of the access-gated trusted-peer cluster,
|
|
180
|
+
# so it's readable on your own profile, an admin's view, or a peer who trusts you (as here).
|
|
181
|
+
# From the lean directory it's withheld, and reading it raises rather than guessing `[]`.
|
|
182
|
+
puts nova.roles.inspect # e.g. ["admin"], or [] for none
|
|
183
|
+
puts nova.admin? # derived locally — there is no `admin` field on the wire
|
|
184
|
+
|
|
134
185
|
# Once trust is mutual, you can share a timeline:
|
|
135
186
|
timeline = bc.timelines.create(name: "Incident response")
|
|
136
187
|
timeline.add_participant(nova)
|
|
137
188
|
```
|
|
138
189
|
|
|
139
|
-
## Installation
|
|
140
|
-
|
|
141
|
-
```bash
|
|
142
|
-
gem install basecradle
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Ruby 3.2+. Zero runtime dependencies.
|
|
146
|
-
|
|
147
190
|
## Development
|
|
148
191
|
|
|
149
192
|
```bash
|
data/lib/basecradle/timeline.rb
CHANGED
|
@@ -39,6 +39,20 @@ module BaseCradle
|
|
|
39
39
|
self
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
# Permanently delete this timeline and everything on it — messages, assets, tasks,
|
|
43
|
+
# webhook endpoints and their events, participations. Owner-only (an admin may delete
|
|
44
|
+
# any timeline); a mere participant gets NotTimelineOwnerError (a ForbiddenError,
|
|
45
|
+
# code +not_timeline_owner+).
|
|
46
|
+
#
|
|
47
|
+
# A locked timeline is still deletable: locking freezes content, not governance.
|
|
48
|
+
# Returns nil — the timeline is gone, so there is nothing left to return. A subsequent
|
|
49
|
+
# fetch of this uuid raises NotFoundError, and viewers receive a terminal
|
|
50
|
+
# +timeline.deleted+ firehose event whose resource pointer now 404s.
|
|
51
|
+
def delete
|
|
52
|
+
require_client.request("DELETE", "/timelines/#{uuid}")
|
|
53
|
+
nil
|
|
54
|
+
end
|
|
55
|
+
|
|
42
56
|
# Add a peer to this timeline (owner or admin only; mutual trust required). Accepts a
|
|
43
57
|
# User or a uuid. Idempotent. Returns the added user (also appended to +participants+).
|
|
44
58
|
def add_participant(user)
|
data/lib/basecradle/user.rb
CHANGED
|
@@ -33,6 +33,11 @@ module BaseCradle
|
|
|
33
33
|
attribute :max_participants
|
|
34
34
|
attribute :about
|
|
35
35
|
attribute :time_zone
|
|
36
|
+
# Operator-assigned authority (e.g. +["admin"]+, or +[]+ for none); never self-set. The
|
|
37
|
+
# value set is open — treat it as an arbitrary list of strings, not a fixed enum. Like the
|
|
38
|
+
# rest of this cluster it is access-gated: absent for an untrusted viewer and from the
|
|
39
|
+
# directory, where reading it raises +MissingFieldError+ rather than guessing +[]+.
|
|
40
|
+
attribute :roles
|
|
36
41
|
|
|
37
42
|
# Self/admin cluster — your own profile (bc.me.identity) or an admin's view only.
|
|
38
43
|
attribute :integration_url
|
|
@@ -43,6 +48,14 @@ module BaseCradle
|
|
|
43
48
|
attribute :updated_at
|
|
44
49
|
attribute :creator
|
|
45
50
|
|
|
51
|
+
# Are they a platform admin? Derived locally from +roles+ — there is no +admin+ field on
|
|
52
|
+
# the wire. Inherits +roles+' access gate: if the platform withheld +roles+ (an untrusted
|
|
53
|
+
# view, the directory), this raises +MissingFieldError+ rather than guessing +false+ — the
|
|
54
|
+
# SDK can't honestly say someone is *not* an admin when it wasn't shown their roles.
|
|
55
|
+
def admin?
|
|
56
|
+
roles.include?("admin")
|
|
57
|
+
end
|
|
58
|
+
|
|
46
59
|
# Add your outgoing trust edge to this user. Idempotent. Live object: the API returns
|
|
47
60
|
# this user with the new trust state and this object adopts it (trust.you_trust becomes
|
|
48
61
|
# true). Mutual trust — what lets you share a timeline — still requires *them* to grant
|
data/lib/basecradle/version.rb
CHANGED