diff --git a/20-agents/aeco/construction/trimble-connect/commands/delete-comment.md b/20-agents/aeco/construction/trimble-connect/commands/delete-comment.md new file mode 100644 index 000000000..0e8236860 --- /dev/null +++ b/20-agents/aeco/construction/trimble-connect/commands/delete-comment.md @@ -0,0 +1,60 @@ +# `trimble-connect.delete-comment` — delete a comment + +Write command. + +## Lifecycle + +`single` — one call, one response + +## Inputs + +| Field | Type | Description | +|---|---|---| +| `region` | string (optional) | The project's `location` (`europe`, `unitedKingdom`, …) — routes the call to that region's host. Omitted: the project's own `location` is looked up. See [Regions](../skills/projects.md#regions). | +| `project-id` | string | Project id. | +| `topic-id` | string | Topic guid. | +| `comment-id` | string | Comment guid. | + +The agent authenticates with the single `trimble-connect` credential from +`aware connect trimble-connect` (the token is refreshed automatically, #198). + +## Outputs + +Handled in-process by the runtime (`cli/src/runtime/trimble_bcf.rs`, floless.app#2184). +BCF lives on Trimble's regional Topics API, not under the agent's Core base, so every +BCF command first resolves the project's region — `GET {core}/projects/{project-id}` +gives its `location`, and the public `GET {core}/regions` maps that to the region's +`topic-api` — and sends the token only to one of the five published Topics hosts +(`open11` / `open21` / `open22` / `open31` / `open32` `.connect.trimble.com`). Redirects +are never followed. A non-2xx **fails the node** with the step, the status and TC's own +message — it is not returned as data. + +```yaml +region: string # the location the call was routed to, when known +comment-id: string +deleted: bool +``` + +## REST translation + +```http +0. GET {core}/projects/{project-id} (Bearer) → location + GET {core}/regions (no auth) → topic-api for that location + {bcf} = {topic-api}bcf/2.1/projects/{project-id} +1. DELETE {bcf}/topics/{topic-id}/comments/{comment-id} (Bearer) → 204 +``` + +## Failure modes + +| Error | Cause | Recovery | +|---|---|---| +| `missing required input …` / `… must be …` | Bad input — refused before any request | Fix the node config | +| `BCF region: project: HTTP 404 …` | No such project, or no access | Check `project-id` with `list-projects` | +| `BCF region: … not a known Trimble Connect Topics host` | TC named a Topics URL outside the published five | Report it; the token was not sent | +| `… redirects are not followed` | TC answered 3xx | Report it | +| `… HTTP 401 …` | Token expired and could not be refreshed | `aware connect trimble-connect --refresh` | + +## See also + +- [topics.md](../skills/topics.md) — the API reference +- [trimble-connect.create-comment](./create-comment.md) diff --git a/20-agents/aeco/construction/trimble-connect/commands/delete-viewpoint.md b/20-agents/aeco/construction/trimble-connect/commands/delete-viewpoint.md new file mode 100644 index 000000000..37877e6b9 --- /dev/null +++ b/20-agents/aeco/construction/trimble-connect/commands/delete-viewpoint.md @@ -0,0 +1,60 @@ +# `trimble-connect.delete-viewpoint` — delete a viewpoint + +Write command. + +## Lifecycle + +`single` — one call, one response + +## Inputs + +| Field | Type | Description | +|---|---|---| +| `region` | string (optional) | The project's `location` (`europe`, `unitedKingdom`, …) — routes the call to that region's host. Omitted: the project's own `location` is looked up. See [Regions](../skills/projects.md#regions). | +| `project-id` | string | Project id. | +| `topic-id` | string | Topic guid. | +| `viewpoint-id` | string | Viewpoint guid. | + +The agent authenticates with the single `trimble-connect` credential from +`aware connect trimble-connect` (the token is refreshed automatically, #198). + +## Outputs + +Handled in-process by the runtime (`cli/src/runtime/trimble_bcf.rs`, floless.app#2184). +BCF lives on Trimble's regional Topics API, not under the agent's Core base, so every +BCF command first resolves the project's region — `GET {core}/projects/{project-id}` +gives its `location`, and the public `GET {core}/regions` maps that to the region's +`topic-api` — and sends the token only to one of the five published Topics hosts +(`open11` / `open21` / `open22` / `open31` / `open32` `.connect.trimble.com`). Redirects +are never followed. A non-2xx **fails the node** with the step, the status and TC's own +message — it is not returned as data. + +```yaml +region: string # the location the call was routed to, when known +viewpoint-id: string +deleted: bool +``` + +## REST translation + +```http +0. GET {core}/projects/{project-id} (Bearer) → location + GET {core}/regions (no auth) → topic-api for that location + {bcf} = {topic-api}bcf/2.1/projects/{project-id} +1. DELETE {bcf}/topics/{topic-id}/viewpoints/{viewpoint-id} (Bearer) → 204 +``` + +## Failure modes + +| Error | Cause | Recovery | +|---|---|---| +| `missing required input …` / `… must be …` | Bad input — refused before any request | Fix the node config | +| `BCF region: project: HTTP 404 …` | No such project, or no access | Check `project-id` with `list-projects` | +| `BCF region: … not a known Trimble Connect Topics host` | TC named a Topics URL outside the published five | Report it; the token was not sent | +| `… redirects are not followed` | TC answered 3xx | Report it | +| `… HTTP 401 …` | Token expired and could not be refreshed | `aware connect trimble-connect --refresh` | + +## See also + +- [topics.md](../skills/topics.md) — the API reference +- [trimble-connect.create-viewpoint](./create-viewpoint.md) diff --git a/20-agents/aeco/construction/trimble-connect/commands/download-bcf-document.md b/20-agents/aeco/construction/trimble-connect/commands/download-bcf-document.md new file mode 100644 index 000000000..35fe13ca1 --- /dev/null +++ b/20-agents/aeco/construction/trimble-connect/commands/download-bcf-document.md @@ -0,0 +1,64 @@ +# `trimble-connect.download-bcf-document` — a project BCF document's bytes + +Stateless read. TC answers with a `302` to a pre-signed file-service URL (seen live); +that one hop is followed — https only, and **without** the token, as `download` does. +Max 256 MiB. + +## Lifecycle + +`single` — one call, one response + +## Inputs + +| Field | Type | Description | +|---|---|---| +| `region` | string (optional) | The project's `location` (`europe`, `unitedKingdom`, …) — routes the call to that region's host. Omitted: the project's own `location` is looked up. See [Regions](../skills/projects.md#regions). | +| `project-id` | string | Project id. | +| `document-id` | string | Document guid. | + +The agent authenticates with the single `trimble-connect` credential from +`aware connect trimble-connect` (the token is refreshed automatically, #198). + +## Outputs + +Handled in-process by the runtime (`cli/src/runtime/trimble_bcf.rs`, floless.app#2184). +BCF lives on Trimble's regional Topics API, not under the agent's Core base, so every +BCF command first resolves the project's region — `GET {core}/projects/{project-id}` +gives its `location`, and the public `GET {core}/regions` maps that to the region's +`topic-api` — and sends the token only to one of the five published Topics hosts +(`open11` / `open21` / `open22` / `open31` / `open32` `.connect.trimble.com`). Redirects +are never followed. A non-2xx **fails the node** with the step, the status and TC's own +message — it is not returned as data. + +```yaml +region: string # the location the call was routed to, when known +bytes: string +encoding: string +size-kb: number +``` + +## REST translation + +```http +0. GET {core}/projects/{project-id} (Bearer) → location + GET {core}/regions (no auth) → topic-api for that location + {bcf} = {topic-api}bcf/2.1/projects/{project-id} +1. GET {bcf}/documents/{document-id} (Bearer) → 302 Location: https://… +2. GET (no auth) → bytes +``` + +## Failure modes + +| Error | Cause | Recovery | +|---|---|---| +| `missing required input …` / `… must be …` | Bad input — refused before any request | Fix the node config | +| `BCF region: project: HTTP 404 …` | No such project, or no access | Check `project-id` with `list-projects` | +| `BCF region: … not a known Trimble Connect Topics host` | TC named a Topics URL outside the published five | Report it; the token was not sent | +| `… redirects are not followed` | TC answered 3xx | Report it | +| `… without an https Location` | TC redirected somewhere unexpected | Report it; nothing was fetched | +| `… HTTP 401 …` | Token expired and could not be refreshed | `aware connect trimble-connect --refresh` | + +## See also + +- [topics.md](../skills/topics.md) — the API reference +- [trimble-connect.upload-bcf-document](./upload-bcf-document.md) diff --git a/20-agents/aeco/construction/trimble-connect/commands/get-project-extensions.md b/20-agents/aeco/construction/trimble-connect/commands/get-project-extensions.md new file mode 100644 index 000000000..47425658e --- /dev/null +++ b/20-agents/aeco/construction/trimble-connect/commands/get-project-extensions.md @@ -0,0 +1,66 @@ +# `trimble-connect.get-project-extensions` — the project's BCF extension values + +Stateless read. Topic types, statuses, labels, priorities and stages are per-project BCF +extensions: `create-topic` / `update-topic` accept only these values (anything else is a +`400 … is not defined in the project extension`). Read them here first. The raw +extensions object (with colours, defaults and the allowed actions) is under `extensions`. + +## Lifecycle + +`single` — one call, one response + +## Inputs + +| Field | Type | Description | +|---|---|---| +| `region` | string (optional) | The project's `location` (`europe`, `unitedKingdom`, …) — routes the call to that region's host. Omitted: the project's own `location` is looked up. See [Regions](../skills/projects.md#regions). | +| `project-id` | string | Project id. | + +The agent authenticates with the single `trimble-connect` credential from +`aware connect trimble-connect` (the token is refreshed automatically, #198). + +## Outputs + +Handled in-process by the runtime (`cli/src/runtime/trimble_bcf.rs`, floless.app#2184). +BCF lives on Trimble's regional Topics API, not under the agent's Core base, so every +BCF command first resolves the project's region — `GET {core}/projects/{project-id}` +gives its `location`, and the public `GET {core}/regions` maps that to the region's +`topic-api` — and sends the token only to one of the five published Topics hosts +(`open11` / `open21` / `open22` / `open31` / `open32` `.connect.trimble.com`). Redirects +are never followed. A non-2xx **fails the node** with the step, the status and TC's own +message — it is not returned as data. + +```yaml +region: string # the location the call was routed to, when known +topic-types: array +topic-statuses: array +topic-labels: array +priorities: array +stages: array +extensions: object +``` + +## REST translation + +```http +0. GET {core}/projects/{project-id} (Bearer) → location + GET {core}/regions (no auth) → topic-api for that location + {bcf} = {topic-api}bcf/2.1/projects/{project-id} +1. GET {bcf}/extensions?includeUsers=false (Bearer) +``` + +## Failure modes + +| Error | Cause | Recovery | +|---|---|---| +| `missing required input …` / `… must be …` | Bad input — refused before any request | Fix the node config | +| `BCF region: project: HTTP 404 …` | No such project, or no access | Check `project-id` with `list-projects` | +| `BCF region: … not a known Trimble Connect Topics host` | TC named a Topics URL outside the published five | Report it; the token was not sent | +| `… redirects are not followed` | TC answered 3xx | Report it | +| `… HTTP 401 …` | Token expired and could not be refreshed | `aware connect trimble-connect --refresh` | + +## See also + +- [topics.md](../skills/topics.md) — the API reference +- [trimble-connect.create-topic](./create-topic.md) +- [trimble-connect.update-topic](./update-topic.md) diff --git a/20-agents/aeco/construction/trimble-connect/commands/get-viewpoint.md b/20-agents/aeco/construction/trimble-connect/commands/get-viewpoint.md new file mode 100644 index 000000000..c95b222f7 --- /dev/null +++ b/20-agents/aeco/construction/trimble-connect/commands/get-viewpoint.md @@ -0,0 +1,63 @@ +# `trimble-connect.get-viewpoint` — one viewpoint + +Stateless read. The viewpoint as TC returns it — cameras, lines, clipping planes, +components, and its snapshot (TC returns a JPEG thumbnail here; use +`get-viewpoint-snapshot` for the full image). + +## Lifecycle + +`single` — one call, one response + +## Inputs + +| Field | Type | Description | +|---|---|---| +| `region` | string (optional) | The project's `location` (`europe`, `unitedKingdom`, …) — routes the call to that region's host. Omitted: the project's own `location` is looked up. See [Regions](../skills/projects.md#regions). | +| `project-id` | string | Project id. | +| `topic-id` | string | Topic guid. | +| `viewpoint-id` | string | Viewpoint guid. | + +The agent authenticates with the single `trimble-connect` credential from +`aware connect trimble-connect` (the token is refreshed automatically, #198). + +## Outputs + +Handled in-process by the runtime (`cli/src/runtime/trimble_bcf.rs`, floless.app#2184). +BCF lives on Trimble's regional Topics API, not under the agent's Core base, so every +BCF command first resolves the project's region — `GET {core}/projects/{project-id}` +gives its `location`, and the public `GET {core}/regions` maps that to the region's +`topic-api` — and sends the token only to one of the five published Topics hosts +(`open11` / `open21` / `open22` / `open31` / `open32` `.connect.trimble.com`). Redirects +are never followed. A non-2xx **fails the node** with the step, the status and TC's own +message — it is not returned as data. + +```yaml +region: string # the location the call was routed to, when known +viewpoint-id: string +viewpoint: object +``` + +## REST translation + +```http +0. GET {core}/projects/{project-id} (Bearer) → location + GET {core}/regions (no auth) → topic-api for that location + {bcf} = {topic-api}bcf/2.1/projects/{project-id} +1. GET {bcf}/topics/{topic-id}/viewpoints/{viewpoint-id} (Bearer) +``` + +## Failure modes + +| Error | Cause | Recovery | +|---|---|---| +| `missing required input …` / `… must be …` | Bad input — refused before any request | Fix the node config | +| `BCF region: project: HTTP 404 …` | No such project, or no access | Check `project-id` with `list-projects` | +| `BCF region: … not a known Trimble Connect Topics host` | TC named a Topics URL outside the published five | Report it; the token was not sent | +| `… redirects are not followed` | TC answered 3xx | Report it | +| `… HTTP 401 …` | Token expired and could not be refreshed | `aware connect trimble-connect --refresh` | + +## See also + +- [topics.md](../skills/topics.md) — the API reference +- [trimble-connect.get-viewpoint-snapshot](./get-viewpoint-snapshot.md) +- [trimble-connect.list-viewpoints](./list-viewpoints.md) diff --git a/20-agents/aeco/construction/trimble-connect/commands/list-bcf-documents.md b/20-agents/aeco/construction/trimble-connect/commands/list-bcf-documents.md new file mode 100644 index 000000000..63e7664f7 --- /dev/null +++ b/20-agents/aeco/construction/trimble-connect/commands/list-bcf-documents.md @@ -0,0 +1,64 @@ +# `trimble-connect.list-bcf-documents` — the project's BCF documents + +Stateless read; every page is read (`next` links followed). On Trimble Connect a BCF document is a project file (verified live): +its `guid` is the file's id in the Files API, and it is what `create-document-reference` +takes as `document-id`. + +## Lifecycle + +`single` — one call, one response + +## Inputs + +| Field | Type | Description | +|---|---|---| +| `region` | string (optional) | The project's `location` (`europe`, `unitedKingdom`, …) — routes the call to that region's host. Omitted: the project's own `location` is looked up. See [Regions](../skills/projects.md#regions). | +| `project-id` | string | Project id. | + +The agent authenticates with the single `trimble-connect` credential from +`aware connect trimble-connect` (the token is refreshed automatically, #198). + +## Outputs + +Handled in-process by the runtime (`cli/src/runtime/trimble_bcf.rs`, floless.app#2184). +BCF lives on Trimble's regional Topics API, not under the agent's Core base, so every +BCF command first resolves the project's region — `GET {core}/projects/{project-id}` +gives its `location`, and the public `GET {core}/regions` maps that to the region's +`topic-api` — and sends the token only to one of the five published Topics hosts +(`open11` / `open21` / `open22` / `open31` / `open32` `.connect.trimble.com`). Redirects +are never followed. A non-2xx **fails the node** with the step, the status and TC's own +message — it is not returned as data. + +```yaml +region: string # the location the call was routed to, when known +items: + type: array + items: + guid: string + filename: string +``` + +## REST translation + +```http +0. GET {core}/projects/{project-id} (Bearer) → location + GET {core}/regions (no auth) → topic-api for that location + {bcf} = {topic-api}bcf/2.1/projects/{project-id} +1. GET {bcf}/documents (Bearer) → [{"guid", "filename"}] +``` + +## Failure modes + +| Error | Cause | Recovery | +|---|---|---| +| `missing required input …` / `… must be …` | Bad input — refused before any request | Fix the node config | +| `BCF region: project: HTTP 404 …` | No such project, or no access | Check `project-id` with `list-projects` | +| `BCF region: … not a known Trimble Connect Topics host` | TC named a Topics URL outside the published five | Report it; the token was not sent | +| `… redirects are not followed` | TC answered 3xx | Report it | +| `… HTTP 401 …` | Token expired and could not be refreshed | `aware connect trimble-connect --refresh` | + +## See also + +- [topics.md](../skills/topics.md) — the API reference +- [trimble-connect.upload-bcf-document](./upload-bcf-document.md) +- [trimble-connect.create-document-reference](./create-document-reference.md) diff --git a/20-agents/aeco/construction/trimble-connect/commands/list-related-topics.md b/20-agents/aeco/construction/trimble-connect/commands/list-related-topics.md new file mode 100644 index 000000000..2580bb6ff --- /dev/null +++ b/20-agents/aeco/construction/trimble-connect/commands/list-related-topics.md @@ -0,0 +1,61 @@ +# `trimble-connect.list-related-topics` — the topics related to a topic + +Stateless read. Every page is read (TC's `next` links are followed by their `skiptoken`), so the list is complete. + +## Lifecycle + +`single` — one call, one response + +## Inputs + +| Field | Type | Description | +|---|---|---| +| `region` | string (optional) | The project's `location` (`europe`, `unitedKingdom`, …) — routes the call to that region's host. Omitted: the project's own `location` is looked up. See [Regions](../skills/projects.md#regions). | +| `project-id` | string | Project id. | +| `topic-id` | string | Topic guid. | + +The agent authenticates with the single `trimble-connect` credential from +`aware connect trimble-connect` (the token is refreshed automatically, #198). + +## Outputs + +Handled in-process by the runtime (`cli/src/runtime/trimble_bcf.rs`, floless.app#2184). +BCF lives on Trimble's regional Topics API, not under the agent's Core base, so every +BCF command first resolves the project's region — `GET {core}/projects/{project-id}` +gives its `location`, and the public `GET {core}/regions` maps that to the region's +`topic-api` — and sends the token only to one of the five published Topics hosts +(`open11` / `open21` / `open22` / `open31` / `open32` `.connect.trimble.com`). Redirects +are never followed. A non-2xx **fails the node** with the step, the status and TC's own +message — it is not returned as data. + +```yaml +region: string # the location the call was routed to, when known +items: + type: array + items: + related_topic_guid: string +``` + +## REST translation + +```http +0. GET {core}/projects/{project-id} (Bearer) → location + GET {core}/regions (no auth) → topic-api for that location + {bcf} = {topic-api}bcf/2.1/projects/{project-id} +1. GET {bcf}/topics/{topic-id}/related_topics (Bearer) → [{"related_topic_guid"}] +``` + +## Failure modes + +| Error | Cause | Recovery | +|---|---|---| +| `missing required input …` / `… must be …` | Bad input — refused before any request | Fix the node config | +| `BCF region: project: HTTP 404 …` | No such project, or no access | Check `project-id` with `list-projects` | +| `BCF region: … not a known Trimble Connect Topics host` | TC named a Topics URL outside the published five | Report it; the token was not sent | +| `… redirects are not followed` | TC answered 3xx | Report it | +| `… HTTP 401 …` | Token expired and could not be refreshed | `aware connect trimble-connect --refresh` | + +## See also + +- [topics.md](../skills/topics.md) — the API reference +- [trimble-connect.set-related-topics](./set-related-topics.md) diff --git a/20-agents/aeco/construction/trimble-connect/commands/list-todo-types.md b/20-agents/aeco/construction/trimble-connect/commands/list-todo-types.md new file mode 100644 index 000000000..a69bedc0c --- /dev/null +++ b/20-agents/aeco/construction/trimble-connect/commands/list-todo-types.md @@ -0,0 +1,47 @@ +# `trimble-connect.list-todo-types` — a project's ToDo types + +Stateless read. The values `create-todo` / `update-todo` accept for `type` in this project. + +## Lifecycle + +`single` — one call, one response + +## Inputs + +| Field | Type | Description | +|---|---|---| +| `region` | string (optional) | The project's `location` (`europe`, `unitedKingdom`, …) — routes the call to that region's host. Omitted: the project's own `location` is looked up. See [Regions](../skills/projects.md#regions). | +| `project-id` | string | Project id. | + +The agent authenticates with the single `trimble-connect` credential from +`aware connect trimble-connect` (the token is refreshed automatically, #198). + +## Outputs + +Handled in-process by the runtime (`cli/src/runtime/trimble_bcf.rs`, floless.app#2184): +it builds TC's camelCase body from the kebab-case inputs, which the generic REST renderer +cannot express. ToDos are Core API 2.0, on the agent's own base. A non-2xx **fails the +node** with the step, the status and TC's own message. + +```yaml +region: string # the location the call was routed to, when known +items: array +``` + +## REST translation + +```http +GET {core}/todos/types?projectId={project-id} (Bearer) → ["Issue", "Request", …] +``` + +## Failure modes + +| Error | Cause | Recovery | +|---|---|---| +| `missing required input …` / `… must be …` | Bad input — refused before any request | Fix the node config | +| `… HTTP 401 …` | Token expired and could not be refreshed | `aware connect trimble-connect --refresh` | + +## See also + +- [projects.md](../skills/projects.md) — the API reference +- [trimble-connect.create-todo](./create-todo.md) diff --git a/20-agents/aeco/construction/trimble-connect/commands/set-related-topics.md b/20-agents/aeco/construction/trimble-connect/commands/set-related-topics.md new file mode 100644 index 000000000..ebfb419b8 --- /dev/null +++ b/20-agents/aeco/construction/trimble-connect/commands/set-related-topics.md @@ -0,0 +1,68 @@ +# `trimble-connect.set-related-topics` — relate topics to a topic + +Write command. BCF's `PUT related_topics` replaces the whole list, so `mode: add` (the +default) reads every page of the current relations first and adds the new ids after them; `mode: +replace` sends exactly the ids given, and an empty list with `replace` clears them. +Duplicates are dropped, and a topic cannot be related to itself. + +## Lifecycle + +`single` — one call, one response + +## Inputs + +| Field | Type | Description | +|---|---|---| +| `region` | string (optional) | The project's `location` (`europe`, `unitedKingdom`, …) — routes the call to that region's host. Omitted: the project's own `location` is looked up. See [Regions](../skills/projects.md#regions). | +| `project-id` | string | Project id. | +| `topic-id` | string | Topic guid. | +| `related-topic-ids` | list | Guids of the topics to relate. | +| `mode` | `add` \| `replace` (optional) | Add to the current relations, or replace them. | + +The agent authenticates with the single `trimble-connect` credential from +`aware connect trimble-connect` (the token is refreshed automatically, #198). + +## Outputs + +Handled in-process by the runtime (`cli/src/runtime/trimble_bcf.rs`, floless.app#2184). +BCF lives on Trimble's regional Topics API, not under the agent's Core base, so every +BCF command first resolves the project's region — `GET {core}/projects/{project-id}` +gives its `location`, and the public `GET {core}/regions` maps that to the region's +`topic-api` — and sends the token only to one of the five published Topics hosts +(`open11` / `open21` / `open22` / `open31` / `open32` `.connect.trimble.com`). Redirects +are never followed. A non-2xx **fails the node** with the step, the status and TC's own +message — it is not returned as data. + +```yaml +region: string # the location the call was routed to, when known +items: + type: array + items: + related_topic_guid: string +``` + +## REST translation + +```http +0. GET {core}/projects/{project-id} (Bearer) → location + GET {core}/regions (no auth) → topic-api for that location + {bcf} = {topic-api}bcf/2.1/projects/{project-id} +1. GET {bcf}/topics/{topic-id}/related_topics (Bearer) — add mode only +2. PUT {bcf}/topics/{topic-id}/related_topics (Bearer) + [ { "related_topic_guid": "…" }, … ] +``` + +## Failure modes + +| Error | Cause | Recovery | +|---|---|---| +| `missing required input …` / `… must be …` | Bad input — refused before any request | Fix the node config | +| `BCF region: project: HTTP 404 …` | No such project, or no access | Check `project-id` with `list-projects` | +| `BCF region: … not a known Trimble Connect Topics host` | TC named a Topics URL outside the published five | Report it; the token was not sent | +| `… redirects are not followed` | TC answered 3xx | Report it | +| `… HTTP 401 …` | Token expired and could not be refreshed | `aware connect trimble-connect --refresh` | + +## See also + +- [topics.md](../skills/topics.md) — the API reference +- [trimble-connect.list-related-topics](./list-related-topics.md) diff --git a/20-agents/aeco/construction/trimble-connect/commands/update-comment.md b/20-agents/aeco/construction/trimble-connect/commands/update-comment.md new file mode 100644 index 000000000..3c9cc2c36 --- /dev/null +++ b/20-agents/aeco/construction/trimble-connect/commands/update-comment.md @@ -0,0 +1,68 @@ +# `trimble-connect.update-comment` — edit a comment + +Write command. Changes the comment's text. The comment is read first, so its viewpoint +and reply-to links are kept unless new ones are given. + +## Lifecycle + +`single` — one call, one response + +## Inputs + +| Field | Type | Description | +|---|---|---| +| `region` | string (optional) | The project's `location` (`europe`, `unitedKingdom`, …) — routes the call to that region's host. Omitted: the project's own `location` is looked up. See [Regions](../skills/projects.md#regions). | +| `project-id` | string | Project id. | +| `topic-id` | string | Topic guid. | +| `comment-id` | string | Comment guid. | +| `comment` | string | New comment text. | +| `viewpoint-id` | string (optional) | New viewpoint guid; kept as it is when omitted. | +| `reply-to-comment-id` | string (optional) | New reply-to comment guid; kept as it is when omitted. | + +The agent authenticates with the single `trimble-connect` credential from +`aware connect trimble-connect` (the token is refreshed automatically, #198). + +## Outputs + +Handled in-process by the runtime (`cli/src/runtime/trimble_bcf.rs`, floless.app#2184). +BCF lives on Trimble's regional Topics API, not under the agent's Core base, so every +BCF command first resolves the project's region — `GET {core}/projects/{project-id}` +gives its `location`, and the public `GET {core}/regions` maps that to the region's +`topic-api` — and sends the token only to one of the five published Topics hosts +(`open11` / `open21` / `open22` / `open31` / `open32` `.connect.trimble.com`). Redirects +are never followed. A non-2xx **fails the node** with the step, the status and TC's own +message — it is not returned as data. + +```yaml +region: string # the location the call was routed to, when known +comment-id: string +comment: object +``` + +## REST translation + +```http +0. GET {core}/projects/{project-id} (Bearer) → location + GET {core}/regions (no auth) → topic-api for that location + {bcf} = {topic-api}bcf/2.1/projects/{project-id} +1. GET {bcf}/topics/{topic-id}/comments/{comment-id} (Bearer) +2. PUT {bcf}/topics/{topic-id}/comments/{comment-id} (Bearer) + { "comment", "viewpoint_guid", "reply_to_comment_guid" } +``` + +## Failure modes + +| Error | Cause | Recovery | +|---|---|---| +| `missing required input …` / `… must be …` | Bad input — refused before any request | Fix the node config | +| `BCF region: project: HTTP 404 …` | No such project, or no access | Check `project-id` with `list-projects` | +| `BCF region: … not a known Trimble Connect Topics host` | TC named a Topics URL outside the published five | Report it; the token was not sent | +| `… redirects are not followed` | TC answered 3xx | Report it | +| `update comment: HTTP 403 …` | Not your comment, or no right to edit it | Check the project's `comment_actions` (get-project-extensions) | +| `… HTTP 401 …` | Token expired and could not be refreshed | `aware connect trimble-connect --refresh` | + +## See also + +- [topics.md](../skills/topics.md) — the API reference +- [trimble-connect.create-comment](./create-comment.md) +- [trimble-connect.delete-comment](./delete-comment.md) diff --git a/20-agents/aeco/construction/trimble-connect/commands/upload-bcf-document.md b/20-agents/aeco/construction/trimble-connect/commands/upload-bcf-document.md new file mode 100644 index 000000000..60434d095 --- /dev/null +++ b/20-agents/aeco/construction/trimble-connect/commands/upload-bcf-document.md @@ -0,0 +1,67 @@ +# `trimble-connect.upload-bcf-document` — upload a project BCF document + +Write command. Sends the file as `multipart/form-data` (the form that carries the file +name). On Trimble Connect it lands as a **file in the project's root folder**; the +returned `document-id` is that file's id. BCF has no delete for documents — remove one +with `delete-file`. Max 256 MiB. + +## Lifecycle + +`single` — one call, one response + +## Inputs + +| Field | Type | Description | +|---|---|---| +| `region` | string (optional) | The project's `location` (`europe`, `unitedKingdom`, …) — routes the call to that region's host. Omitted: the project's own `location` is looked up. See [Regions](../skills/projects.md#regions). | +| `project-id` | string | Project id. | +| `filename` | string | File name (no path). | +| `bytes` | bytes | File content, base64 (max 256 MiB). | + +The agent authenticates with the single `trimble-connect` credential from +`aware connect trimble-connect` (the token is refreshed automatically, #198). + +## Outputs + +Handled in-process by the runtime (`cli/src/runtime/trimble_bcf.rs`, floless.app#2184). +BCF lives on Trimble's regional Topics API, not under the agent's Core base, so every +BCF command first resolves the project's region — `GET {core}/projects/{project-id}` +gives its `location`, and the public `GET {core}/regions` maps that to the region's +`topic-api` — and sends the token only to one of the five published Topics hosts +(`open11` / `open21` / `open22` / `open31` / `open32` `.connect.trimble.com`). Redirects +are never followed. A non-2xx **fails the node** with the step, the status and TC's own +message — it is not returned as data. + +```yaml +region: string # the location the call was routed to, when known +document-id: string +filename: string +``` + +## REST translation + +```http +0. GET {core}/projects/{project-id} (Bearer) → location + GET {core}/regions (no auth) → topic-api for that location + {bcf} = {topic-api}bcf/2.1/projects/{project-id} +1. POST {bcf}/documents (Bearer) + Content-Type: multipart/form-data; boundary=… + file=; filename="{filename}" + → 201 {"guid", "filename"} +``` + +## Failure modes + +| Error | Cause | Recovery | +|---|---|---| +| `missing required input …` / `… must be …` | Bad input — refused before any request | Fix the node config | +| `BCF region: project: HTTP 404 …` | No such project, or no access | Check `project-id` with `list-projects` | +| `BCF region: … not a known Trimble Connect Topics host` | TC named a Topics URL outside the published five | Report it; the token was not sent | +| `… redirects are not followed` | TC answered 3xx | Report it | +| `… HTTP 401 …` | Token expired and could not be refreshed | `aware connect trimble-connect --refresh` | + +## See also + +- [topics.md](../skills/topics.md) — the API reference +- [trimble-connect.create-document-reference](./create-document-reference.md) +- [trimble-connect.list-bcf-documents](./list-bcf-documents.md) diff --git a/20-agents/aeco/construction/trimble-connect/manifest.yaml b/20-agents/aeco/construction/trimble-connect/manifest.yaml index 6b25df1b7..230f2e745 100644 --- a/20-agents/aeco/construction/trimble-connect/manifest.yaml +++ b/20-agents/aeco/construction/trimble-connect/manifest.yaml @@ -1398,6 +1398,325 @@ commands: todo-id: string deleted: bool + list-todo-types: + lifecycle: single + description: The ToDo types a project defines (values for create-todo's `type`). + inputs: + region: + type: string + required: false + description: | + The project's region: its `location` as `get-project` / `list-projects` + return it (`northAmerica`, `europe`, `unitedKingdom`, `asia`, `australia`). + Routes the call to that region's host. Omitted: the project's own location is looked up. + project-id: + type: string + description: Project id. + outputs: + type: single + schema: + region: string # the location the call was routed to, when known + items: array + + # ── more BCF (runtime handler — cli/src/runtime/trimble_bcf.rs) ─────────── + + get-project-extensions: + lifecycle: single + description: | + The project's BCF extension values — the topic types, statuses, labels, + priorities and stages create-topic / update-topic accept. + inputs: + region: + type: string + required: false + description: | + The project's region: its `location` as `get-project` / `list-projects` + return it (`northAmerica`, `europe`, `unitedKingdom`, `asia`, `australia`). + Routes the call to that region's host. Omitted: the project's own location is looked up. + project-id: + type: string + description: Project id. + outputs: + type: single + schema: + region: string # the location the call was routed to, when known + topic-types: array + topic-statuses: array + topic-labels: array + priorities: array + stages: array + extensions: object # the raw BCF extensions object + + list-related-topics: + lifecycle: single + description: The topics related to a topic. + inputs: + region: + type: string + required: false + description: | + The project's region: its `location` as `get-project` / `list-projects` + return it (`northAmerica`, `europe`, `unitedKingdom`, `asia`, `australia`). + Routes the call to that region's host. Omitted: the project's own location is looked up. + project-id: + type: string + description: Project id. + topic-id: + type: string + description: Topic guid. + outputs: + type: single + schema: + region: string # the location the call was routed to, when known + items: + type: array + items: + related_topic_guid: string + + set-related-topics: + lifecycle: single + mode: write + description: | + Relate topics to a topic. BCF replaces the whole list, so `mode: add` (the + default) reads the current relations and adds to them; `replace` sends + exactly the ids given (an empty list clears them). + inputs: + region: + type: string + required: false + description: | + The project's region: its `location` as `get-project` / `list-projects` + return it (`northAmerica`, `europe`, `unitedKingdom`, `asia`, `australia`). + Routes the call to that region's host. Omitted: the project's own location is looked up. + project-id: + type: string + description: Project id. + topic-id: + type: string + description: Topic guid. + related-topic-ids: + type: list + description: Guids of the topics to relate. + mode: + type: enum + values: [add, replace] + default: add + required: false + description: Add to the current relations, or replace them. + outputs: + type: single + schema: + region: string # the location the call was routed to, when known + items: + type: array + items: + related_topic_guid: string + + update-comment: + lifecycle: single + mode: write + description: Edit a comment's text (and optionally its viewpoint or reply-to link). + inputs: + region: + type: string + required: false + description: | + The project's region: its `location` as `get-project` / `list-projects` + return it (`northAmerica`, `europe`, `unitedKingdom`, `asia`, `australia`). + Routes the call to that region's host. Omitted: the project's own location is looked up. + project-id: + type: string + description: Project id. + topic-id: + type: string + description: Topic guid. + comment-id: + type: string + description: Comment guid. + comment: + type: string + description: New comment text. + viewpoint-id: + type: string + required: false + description: New viewpoint guid; kept as it is when omitted. + reply-to-comment-id: + type: string + required: false + description: New reply-to comment guid; kept as it is when omitted. + outputs: + type: single + schema: + region: string # the location the call was routed to, when known + comment-id: string + comment: object + + delete-comment: + lifecycle: single + mode: write + description: Delete a comment. + inputs: + region: + type: string + required: false + description: | + The project's region: its `location` as `get-project` / `list-projects` + return it (`northAmerica`, `europe`, `unitedKingdom`, `asia`, `australia`). + Routes the call to that region's host. Omitted: the project's own location is looked up. + project-id: + type: string + description: Project id. + topic-id: + type: string + description: Topic guid. + comment-id: + type: string + description: Comment guid. + outputs: + type: single + schema: + region: string # the location the call was routed to, when known + comment-id: string + deleted: bool + + get-viewpoint: + lifecycle: single + description: One viewpoint — cameras, lines, clipping planes, components, snapshot. + inputs: + region: + type: string + required: false + description: | + The project's region: its `location` as `get-project` / `list-projects` + return it (`northAmerica`, `europe`, `unitedKingdom`, `asia`, `australia`). + Routes the call to that region's host. Omitted: the project's own location is looked up. + project-id: + type: string + description: Project id. + topic-id: + type: string + description: Topic guid. + viewpoint-id: + type: string + description: Viewpoint guid. + outputs: + type: single + schema: + region: string # the location the call was routed to, when known + viewpoint-id: string + viewpoint: object + + delete-viewpoint: + lifecycle: single + mode: write + description: Delete a viewpoint. + inputs: + region: + type: string + required: false + description: | + The project's region: its `location` as `get-project` / `list-projects` + return it (`northAmerica`, `europe`, `unitedKingdom`, `asia`, `australia`). + Routes the call to that region's host. Omitted: the project's own location is looked up. + project-id: + type: string + description: Project id. + topic-id: + type: string + description: Topic guid. + viewpoint-id: + type: string + description: Viewpoint guid. + outputs: + type: single + schema: + region: string # the location the call was routed to, when known + viewpoint-id: string + deleted: bool + + list-bcf-documents: + lifecycle: single + description: | + The project's BCF documents. On Trimble Connect these are project files (an + upload lands in the project's root folder), and their ids are what + create-document-reference's `document-id` takes. + inputs: + region: + type: string + required: false + description: | + The project's region: its `location` as `get-project` / `list-projects` + return it (`northAmerica`, `europe`, `unitedKingdom`, `asia`, `australia`). + Routes the call to that region's host. Omitted: the project's own location is looked up. + project-id: + type: string + description: Project id. + outputs: + type: single + schema: + region: string # the location the call was routed to, when known + items: + type: array + items: + guid: string + filename: string + + upload-bcf-document: + lifecycle: single + mode: write + description: | + Upload a file as a project BCF document, to reference from topics. On Trimble + Connect it lands as a file in the project's root folder (BCF has no delete — + remove it with delete-file). + inputs: + region: + type: string + required: false + description: | + The project's region: its `location` as `get-project` / `list-projects` + return it (`northAmerica`, `europe`, `unitedKingdom`, `asia`, `australia`). + Routes the call to that region's host. Omitted: the project's own location is looked up. + project-id: + type: string + description: Project id. + filename: + type: string + description: File name (no path). + bytes: + type: bytes + description: File content, base64 (max 256 MiB). + outputs: + type: single + schema: + region: string # the location the call was routed to, when known + document-id: string # also the file's id in the Files API + filename: string + + download-bcf-document: + lifecycle: single + description: A project BCF document's bytes, base64. + inputs: + region: + type: string + required: false + description: | + The project's region: its `location` as `get-project` / `list-projects` + return it (`northAmerica`, `europe`, `unitedKingdom`, `asia`, `australia`). + Routes the call to that region's host. Omitted: the project's own location is looked up. + project-id: + type: string + description: Project id. + document-id: + type: string + description: Document guid. + outputs: + type: single + schema: + region: string # the location the call was routed to, when known + bytes: string # base64-encoded content + encoding: string # "base64" + size-kb: number + skills: - auth-flow.md - idempotency.md diff --git a/20-agents/aeco/construction/trimble-connect/skills/projects.md b/20-agents/aeco/construction/trimble-connect/skills/projects.md index 995cdbdbd..44a593de5 100644 --- a/20-agents/aeco/construction/trimble-connect/skills/projects.md +++ b/20-agents/aeco/construction/trimble-connect/skills/projects.md @@ -260,7 +260,7 @@ definition `api.swaggerhub.com/apis/Trimble-Connect/tcps/2.0` and live, 2026-10- | Create | `POST /todos` | `create-todo` | | Update | `PATCH /todos/{todoId}` (only the fields sent change) | `update-todo` | | Delete | `DELETE /todos/{todoId}` → 204 | `delete-todo` | -| Types | `GET /todos/types?projectId={id}` — the project's ToDo types | — | +| Types | `GET /todos/types?projectId={id}` — the project's ToDo types | `list-todo-types` | ### Create ToDo @@ -421,6 +421,11 @@ foreach (var file in doc.RootElement.EnumerateArray()) ## Project-Level BCF Documents +On Trimble Connect a BCF document **is a project file** (verified live, 2026-10-11): an upload +lands in the project's root folder, its `guid` is the file's id in the Files API, the GET answers +with a `302` to a pre-signed file-service URL, and BCF offers no delete (use the Files API — AWARE +`delete-file`). AWARE: `list-bcf-documents`, `upload-bcf-document`, `download-bcf-document`. + ### List BCF Documents ``` diff --git a/20-agents/aeco/construction/trimble-connect/skills/rate-limits.md b/20-agents/aeco/construction/trimble-connect/skills/rate-limits.md index 4c35a3cb8..35f753cb5 100644 --- a/20-agents/aeco/construction/trimble-connect/skills/rate-limits.md +++ b/20-agents/aeco/construction/trimble-connect/skills/rate-limits.md @@ -33,15 +33,18 @@ fail → the node fails with `… (after 3 attempts): HTTP 429 (rate limite When Trimble returns `Retry-After`, the agent honors that value instead of its own backoff. -**Where this is implemented today:** the BCF topic and ToDo handler commands -(`cli/src/runtime/trimble_bcf.rs`) retry exactly this way, with two safety limits: a `429` is retried -for every method (TC did not process the request), but a `5xx` or a dropped connection is retried only -for GET / PUT / PATCH — a POST may already have created the topic or comment, and a repeated DELETE -would turn the first one's success into a 404. Waits are capped at 30 s. The folder / file / upload -commands do not retry yet. The declarative REST reads (`list-projects`, `get-file`, `get-todo`, …) -return the HTTP exchange as data — a `429` arrives as `status: 429` with its `retry-after` header — -and are not retried. There is no structured `error.rate-limit-exceeded` code yet; a throttled -failure is recognisable by `HTTP 429 (rate limited; Retry-After: …)` in its message. +**How it is implemented:** every handled command — folders, files, upload / download, BCF, ToDos — +goes through one retry helper (`fetch` in `cli/src/runtime/trimble_files.rs`). A request counts +only once its whole body has been read, so a connection that drops mid-body is retried like one +that drops before the headers, from the same budget of three requests. Two safety limits: a `429` +is retried for every method (TC did not process the request), but a `5xx`, a dropped connection or +a cut-off body is retried only for GET / PUT / PATCH (and the pre-signed upload PUT) — a POST +may already have created the folder, topic or comment, and a repeated DELETE would turn the first +one's success into a 404. Waits are capped at 30 s; an error after a retry says `(after N +attempts)`. The declarative REST reads (`list-projects`, `get-file`, `get-todo`, …) return the HTTP +exchange as data — a `429` arrives as `status: 429` with its `retry-after` header — and are not +retried. There is no structured `error.rate-limit-exceeded` code yet (#688); a throttled failure is +recognisable by `HTTP 429 (rate limited; Retry-After: …)` in its message. After 3 attempts the error surfaces to the composition. Do **not** catch it and retry from the app — the agent already did the right thing. A composition that hits this needs upstream throttling, not downstream retry. diff --git a/20-agents/aeco/construction/trimble-connect/skills/topics.md b/20-agents/aeco/construction/trimble-connect/skills/topics.md index ca0ee0bb6..2af742cb9 100644 --- a/20-agents/aeco/construction/trimble-connect/skills/topics.md +++ b/20-agents/aeco/construction/trimble-connect/skills/topics.md @@ -36,6 +36,11 @@ The same Trimble Identity bearer token works there. | List / create comments | `list-comments`, `create-comment` | | List / create viewpoints, fetch a snapshot | `list-viewpoints`, `create-viewpoint`, `get-viewpoint-snapshot` (see viewpoints.md) | | List / create document references | `list-document-references`, `create-document-reference` | +| Edit / delete comments | `update-comment`, `delete-comment` | +| One viewpoint, delete a viewpoint | `get-viewpoint`, `delete-viewpoint` | +| Related topics | `list-related-topics`, `set-related-topics` (`mode: add` reads then adds; `replace`) | +| Allowed types / statuses / labels / priorities / stages | `get-project-extensions` | +| Project BCF documents | `list-bcf-documents`, `upload-bcf-document`, `download-bcf-document` | The commands resolve the region as above and send the token only to the five published Topics hosts. Pass the project's `location` as `region` to skip step 1 (it saves up to five @@ -460,7 +465,8 @@ Content-Type: application/json ] ``` -**Note:** No AWARE command wraps this endpoint yet. +**AWARE:** `list-related-topics`; `set-related-topics` with `mode: add` (the default) does the +read-then-add for you, `mode: replace` sends exactly the list. --- diff --git a/40-diagrams/substrate-playground.html b/40-diagrams/substrate-playground.html index b86932189..e2f59dfb8 100644 --- a/40-diagrams/substrate-playground.html +++ b/40-diagrams/substrate-playground.html @@ -90,7 +90,7 @@

Prompt — copy back to Claude