Add AI agent documentation and clean up dependencies#18
Conversation
…spot crate - Introduced `api.md` for consumer-facing API reference, detailing installation, authentication, client initialization, and usage examples for CRM objects, batch operations, associations, engagements, and error handling. - Created `architecture.md` to outline internal design goals, module dependency flow, core abstractions, and extension points for adding new CRM object types and engagement types. - Added `api_configs.md` to document the generic API infrastructure layer, including `ApiCollection`, `AssociationsApiCollection`, and `BatchApiCollection` functionalities. - Documented the `client` module, detailing the `HubspotClient`, its internal methods, and error handling mechanisms. - Established `engagements.md` to describe the `EngagementType`, `EngagementsManager`, and `NoteProperties` struct, along with examples for creating notes and managing associations. - Provided `objects.md` to explain the `ObjectType` enum and `ObjectsManager`, including methods for CRUD operations and dynamic object type resolution. - Added `owners.md` to outline the `Owner` and `Team` structs, along with the `OwnerApi` for fetching owner details by ID.
- Remove unused async-trait dependency - Replace unmaintained dotenv with dotenvy (maintained fork) in dev-deps - Bump strum/strum_macros from 0.27 to 0.28 reqwest 0.12 → 0.13 deferred (hyper 1.0 change, requires dedicated testing)
There was a problem hiding this comment.
Pull request overview
Adds AI-agent oriented documentation and expands crate documentation while doing a doc-comment audit and routine dependency cleanup.
Changes:
- Adds new top-level and module-level documentation (
CLAUDE.md,llms.txt,docs/*,.github/copilot-instructions.md) intended to guide contributors and AI agents. - Promotes/expands Rust doc comments across the public API surface (structs/enums/fields/methods).
- Cleans up dependencies (remove unused
async-trait, switchdotenv→dotenvy, bumpstrum).
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 26 comments.
Show a summary per file
| File | Description |
|---|---|
src/owners.rs |
Converts field comments to Rustdoc for Owner. |
src/objects.rs |
Adds Rustdoc for ObjectType and ObjectsManager::new(). |
src/lib.rs |
Improves crate-level docs for Hubspot and Hubspot::builder(). |
src/engagements/notes.rs |
Adds Rustdoc for NoteProperties and constructor. |
src/engagements/mod.rs |
Adds Rustdoc for EngagementType and EngagementsManager::new(). |
src/client/error.rs |
Documents HubSpot structured error response types and fields. |
src/builder.rs |
Improves Rustdoc for HubspotBuilder and builder methods. |
src/api_configs/types.rs |
Adds Rustdoc for association/paging/links types. |
src/api_configs/mod.rs |
Documents ApiCollection sub-collections. |
src/api_configs/batch.rs |
Adds Rustdoc for BatchApiCollection. |
src/api_configs/associations.rs |
Adds Rustdoc for associations types/collection. |
llms.txt |
Adds llms.txt index for external LLM discoverability. |
docs/modules/owners.md |
Adds module reference documentation for owners. |
docs/modules/objects.md |
Adds module reference documentation for objects. |
docs/modules/engagements.md |
Adds module reference documentation for engagements/notes. |
docs/modules/client.md |
Adds module reference documentation for client/errors. |
docs/modules/api_configs.md |
Adds module reference documentation for generic API layer. |
docs/architecture.md |
Adds architecture deep-dive and extension guides. |
docs/api.md |
Adds consumer-facing API reference and examples. |
CLAUDE.md |
Adds Claude agent entry point: commands, module map, conventions. |
Cargo.toml |
Removes async-trait, bumps strum, switches dev-dep to dotenvy. |
.github/copilot-instructions.md |
Adds always-on Copilot workspace instructions and conventions. |
Comments suppressed due to low confidence (2)
docs/modules/client.md:100
- This section claims
HubspotErrorResponse/HubspotErrorContextare not part of the public API and that onlymessageis extracted, but insrc/client/error.rsboth structs are declaredpubandFrom<HubspotErrorResponse>formats"{category}: {message}, {context:?}". Please update the wording/snippet to match the current visibility and formatting behavior.
## `HubspotErrorResponse` (internal)
Used to deserialize HubSpot's structured error JSON before converting to `HubspotError::Hubspot(message)`.
```rust
struct HubspotErrorResponse {
pub message: String,
pub context: HubspotErrorContext,
pub category: String,
}
struct HubspotErrorContext {
pub properties: Vec<String>,
}
These types are not part of the public API. When HubSpot returns a 4xx/5xx with a JSON body matching this shape, send() extracts message and returns HubspotError::Hubspot(message).
**src/lib.rs:38**
* Several new docs import `hubspot::client::error::HubspotError`, but `client` is a private module (`mod client;`). Consider re-exporting `HubspotError`/`HubspotResult` (and any other intended public types) from the crate root or making `client` a public module so the documented error-handling examples are actually usable by crate consumers.
/// An unofficial async Rust client for the HubSpot CRM API.
///
/// Construct via [Hubspot::builder()].
#[derive(Clone, Debug)]
pub struct Hubspot {
/// The HubSpot portal (account) ID.
pub portal_id: String,
/// Objects represent types of relationships or processes.
pub objects: ObjectsManager,
/// Engagements store data from interactions with records.
pub engagements: EngagementsManager,
/// Owners are specific users assigned to contacts, companies, deals, tickets, or engagements.
pub owners: OwnerApi,
}
</details>
---
💡 <a href="/WORK180/hubspot-api/new/main?filename=.github/instructions/*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Fix ApiCollection::list() archived param: bool -> Option<bool> - Fix ApiCollection::update() signature: (id: &str, HubspotRecord) -> (id: String, properties: P) - Fix ApiCollection::archive() id type: &str -> String - Fix AssociationsApiCollection::list() signature: add limit/after params, to_object_type: &str not impl ToPath - Fix AssociationsApiCollection::create() signature: (to_object_type: O, to_object_id, Vec<AssociationCreationDetails>) - Fix BatchResult timestamps: Option<OffsetDateTime> -> String (raw API strings) - Fix AssociationLinks enum: remove incorrect integer discriminants, add build() method note - Fix HubspotRecord: remove broken code snippet fragment, add proper struct definition - Fix ObjectApi::name() return type: &str -> &T - Remove entire duplicate second copy of all sections (297 lines)
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 22 out of 22 changed files in this pull request and generated 9 comments.
Comments suppressed due to low confidence (1)
docs/modules/client.md:96
- The description of
HubspotErrorResponseconversion sayssend()extractsmessageand returnsHubspotError::Hubspot(message), butHubspotErrorResponseis converted viaFrom<HubspotErrorResponse>which formatscategory,message, andcontext. Please align this explanation with the actual conversion.
## `HubspotErrorResponse` (internal)
Used to deserialize HubSpot's structured error JSON before converting to `HubspotError::Hubspot(message)`.
```rust
struct HubspotErrorResponse {
pub message: String,
pub context: HubspotErrorContext,
pub category: String,
}
struct HubspotErrorContext {
pub properties: Vec<String>,
}
These types are not part of the public API. When HubSpot returns a 4xx/5xx with a JSON body matching this shape, send() extracts message and returns HubspotError::Hubspot(message).
</details>
---
💡 <a href="/WORK180/hubspot-api/new/main?filename=.github/instructions/*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.
| ### `AssociationLinks` — Hardcoded Built-in Type IDs | ||
|
|
||
| HubSpot assigns numeric IDs to standard ("built-in") association types. These are encoded in the `AssociationLinks` enum to eliminate magic numbers in calling code: | ||
|
|
||
| ```rust | ||
| pub enum AssociationLinks { | ||
| NoteToContact = 202, | ||
| NoteToCompany = 190, | ||
| NoteToDeal = 214, | ||
| } | ||
| ``` |
There was a problem hiding this comment.
This section shows AssociationLinks variants with numeric discriminants, but in code (src/api_configs/types.rs) the IDs are produced via AssociationLinks::build() (the enum has no discriminants). The example should be updated to reflect the actual representation to avoid incorrect extension guidance.
| | Variant | When it occurs | | ||
| |---|---| | ||
| | `Json(serde_json::Error)` | The response body could not be deserialized into the expected type | | ||
| | `Http(reqwest::Error)` | Network failure, connection timeout, or non-success HTTP status from `reqwest` | | ||
| | `Hubspot(String)` | HubSpot returned a structured error response; the `message` field is extracted and stored | | ||
|
|
There was a problem hiding this comment.
This table/section implies HubspotError::Hubspot stores only the API message, but From<HubspotErrorResponse> formats category, message, and context into the string. The docs should reflect that the stored string includes more than just message (or adjust the conversion if the intent is message-only).
- docs/modules/owners.md: fix OwnerApi::read archived param bool -> Option<bool> - docs/modules/client.md: begin() does not pre-apply auth (auth is in send()); fix HubspotErrorResponse conversion format (category: message, context) not just message; fix struct visibility (pub not private) - docs/modules/engagements.md: fix associations.create example — to_object_id is a separate arg; AssociationCreationDetails uses category/type_id fields not association_type - docs/architecture.md: remove AssociationLinks integer discriminants (plain enum + build()); fix begin() description to note auth is in send(); update new association type guidance to reference build() method - CLAUDE.md: fix AssociationLinks bullets to show plain variants with build() IDs; fix ObjectApi::name return type &str -> &T
chanelmoreno
left a comment
There was a problem hiding this comment.
I don't think I've seen this repo before! The docs look aligned to the other repos docs though so
@chanelmoreno made 1 comment.
Reviewable status: 0 of 22 files reviewed, 17 unresolved discussions (waiting on robmarto and tonisefton).
chanelmoreno
left a comment
There was a problem hiding this comment.
@chanelmoreno made 1 comment.
Reviewable status: 0 of 22 files reviewed, 17 unresolved discussions (waiting on robmarto and tonisefton).
robmarto
left a comment
There was a problem hiding this comment.
@robmarto made 1 comment.
Reviewable status: 0 of 22 files reviewed, 18 unresolved discussions (waiting on tonisefton).
.github/copilot-instructions.md line 1 at r3 (raw file):
# Copilot Workspace Instructions — hubspot-api
this should be the same as the CLAUDE.md file as they are both entry points for different tools. claude.md is for ClaudeCode and this is for Github Copilot.
I think its fine to just have copilot instructions reference the claude md file.
tonisefton
left a comment
There was a problem hiding this comment.
@tonisefton made 1 comment and resolved 10 discussions.
Reviewable status: 0 of 22 files reviewed, 1 unresolved discussion (waiting on robmarto).
.github/copilot-instructions.md line 1 at r3 (raw file):
Previously, robmarto (Rob Martin) wrote…
this should be the same as the CLAUDE.md file as they are both entry points for different tools. claude.md is for ClaudeCode and this is for Github Copilot.
I think its fine to just have copilot instructions reference the claude md file.
Done.
robmarto
left a comment
There was a problem hiding this comment.
@robmarto made 1 comment and resolved 1 discussion.
Reviewable status: 0 of 22 files reviewed, all discussions resolved.
Summary
Adds comprehensive documentation for AI agents (Copilot, Claude, etc.), audits and fixes all source doc comments, performs routine dependency maintenance, and adds an
llms.txtfor external LLM discoverability.AI Agent Documentation
.github/copilot-instructions.md— Always-on Copilot workspace instructions: crate purpose, module map, key patterns, conventions, known issuesCLAUDE.md— Claude agent entry point with build/test commands and step-by-step extension guidellms.txt— External LLM index (llmstxt.org standard) linking to crates.io, docs.rs, and all reference docsdocs/architecture.md— Contributor deep-dive: design goals, v3/v4 API endpoint breakdown per operation, core abstractions, HubSpot API reference linksdocs/api.md— Consumer quick-start and full API reference (CRUD, batch, associations, engagements, owners, errors)docs/modules/— Per-module reference docs forobjects,engagements,owners,api_configs, andclientAlso corrects the
.key()→.token()README mismatch throughout all new docs, and documents the v3/v4 mixed API versioning that was previously undocumented.Doc Comment Audit
Reviewed all source files and fixed doc comments throughout the crate:
//regular comments to///doc comments on 8 fields acrossowners.rs,builder.rs,api_configs/types.rs, andapi_configs/associations.rsObjectType,EngagementType,NoteProperties,HubspotErrorContext,HubspotErrorResponse,AssociationsApiCollection,BatchApiCollection,PagingNext, and more)Hubspot::builder(),HubspotBuilder)cargo doc --no-depspasses with zero warningsDependencies
async-traitdependencydotenvdev-dep withdotenvy(maintained fork)strum/strum_macros0.27 → 0.28No version bump required — all changes are internal or dev-only.
This change is