@specset/cli 0.6.0 → 2.0.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.
@@ -9,7 +9,7 @@ allowed-tools: Bash Read AskUserQuestion
9
9
  How the data is shaped:
10
10
 
11
11
  - `status` (SubmittalStatus: `Draft | Open | Closed`) is the log lifecycle; `workingStatus` (SubmittalWorkingStatus: `Draft | Submitted | Pending | Approved | ApprovedAsNoted | Rejected | ReviseAndResubmit | ForRecordOnly | Void`) is the ball-in-court state. Set either — the server reconciles the other.
12
- - Revisions are separate submittal records sharing a `submittalNumber`; list and search queries return only the current revision.
12
+ - Revisions are separate submittal records linked through `parentSubmittal` (the chain, not a shared number, defines a revision); list and search queries return only the current revision.
13
13
  - A submittal number is only unique per (spec section, number) within a project — the bare number alone is not.
14
14
 
15
15
  The sketches below are minimal — inline enums, ints, and lists in the operation text (`-F` is strings-only; Variable Limitations and Schema Discovery live in the `specset` skill).
@@ -39,7 +39,7 @@ Also available:
39
39
 
40
40
  - `paginatedSubmittals(projectId, search, limit: 25, offset: 0) { totalFilteredCount items { ... } }` — offset pagination with text search.
41
41
  - `searchSubmittals(projectId, search)` — lightweight lookup by number or title; use it for dedupe checks.
42
- - `submittalRevisions(projectId, submittalNumber, specSectionId)` — every revision of one number.
42
+ - `submittalRevisions(id)` — every revision in the given submittal's chain (itself included), highest revision first.
43
43
  - `submittalTypes(projectId) { id name label }` — the project's configured types, for `submittalTypeId`.
44
44
 
45
45
  ## Creating
@@ -66,6 +66,8 @@ specset api --query 'mutation($id: ID!) {
66
66
 
67
67
  The revision string auto-increments (`0` → `1`, `A` → `B`); pass `revision` only when the document shows one that doesn't match. `autoReviewMode` works here too.
68
68
 
69
+ A submittal created from a PDF that identifies an existing current submittal (same section and number, higher revision or a package that presents itself as a resubmittal) is linked as its next revision automatically. `unlinkSubmittalRevision(id) { id revision isCurrent parentSubmittal { id } }` detaches a wrongly linked row: it becomes a separate submittal with the number from its own document and the previous revision becomes current again.
70
+
69
71
  ## Attachments
70
72
 
71
73
  File ids come from Uploading Files in the `specset` skill.
@@ -6,7 +6,7 @@ allowed-tools: Bash Read AskUserQuestion
6
6
 
7
7
  # Specset Agent Tools (`specset tools`, `specset mcp`)
8
8
 
9
- These are the same read-only retrieval tools Specset's own in-app agent uses — exposed so external agents can call them directly. Everything here is read-only; nothing needs user confirmation.
9
+ These are the same read-only retrieval tools Specset's own in-app agent uses — exposed so external agents can call them directly.
10
10
 
11
11
  ## When to use which surface
12
12
 
@@ -20,8 +20,9 @@ There are three tiers of Specset retrieval. Pick the lightest one that answers t
20
20
 
21
21
  ```bash
22
22
  specset tools list
23
- specset tools list --project <projectId|sb://project/...>
23
+ specset tools list --project <projectId|https://app.specbook.ai/go/project/...>
24
24
  specset tools list --json # full input schemas
25
+ specset tools list --org <slug> # catalog for an org other than the active one
25
26
  ```
26
27
 
27
28
  The listing includes usage guidance and marks project-scoped tools. The exact set depends on the org (closeout and schedule tools require their SKUs) and on whether a project is in scope.
@@ -40,42 +41,80 @@ specset tools run searchSpecSections \
40
41
  specset tools run searchSpecSections --project <projectId> \
41
42
  -F query="fire rating" -F keywords='["ASTM E119"]' -F limit=5
42
43
 
43
- # Read a specific section's full content using an ID from a search result
44
- specset tools run getSpecSectionContent -F id='sb://spec/....'
44
+ # Read a specific section's full content using a source link from a search result
45
+ specset tools run getSpecSectionContent \
46
+ -F id='https://app.specbook.ai/go/spec/<uuid>'
45
47
  ```
46
48
 
47
49
  Output is the tool's JSON payload (`{ success, message?, result? }`); a `{ success: false }` payload exits non-zero.
48
50
 
49
- ### Identifiers are citation IDs, not links
51
+ ### Source links
50
52
 
51
- Tool results embed identifiers shaped like `sb://spec/<uuid>` or `sb://drawing/<uuid>`. Pass them back into other tools verbatim (e.g. into `getSpecSectionContent`, `getDrawingSheet`). They are citation identifiers, not web URLs.
53
+ Tool results expose clickable links shaped like `https://app.specbook.ai/go/spec/<uuid>` or `https://app.specbook.ai/go/drawing/<uuid>`. Pass them back into other tools verbatim (for example, into `getSpecSectionContent` or `getDrawingSheet`). Include the most relevant returned links as descriptive Markdown citations in user-facing answers. Never invent a link or construct one from an unrelated UUID. An identifier that is not an `https://` link (a thread-local short id or `doc:`-prefixed identifier) is internal — pass it back into tools verbatim, but never present it to the user as a clickable link.
52
54
 
53
55
  ### Project scoping
54
56
 
55
- Most tools are project-scoped. Either pass `--project` (a UUID or `sb://project/...`), or include `projectId` in the tool input. Use `listProjects` to discover project IDs. With `--project` set, per-call `projectId` becomes optional.
57
+ Most tools are project-scoped. Either pass `--project` (a UUID or returned `/go/project/...` link), or include `projectId` in the tool input. Use `listProjects` to discover projects. With `--project` set, per-call `projectId` becomes optional.
58
+
59
+ Tools use the selected organization on the chosen host, or infer the sole membership when none is selected. Pass `--org <slug|id>` on `tools list` and `tools run` to pin a different org — required when the project belongs to an org other than the active one (the call otherwise fails with "Project … not found"), and safer in parallel sessions because the active org is shared config.
56
60
 
57
61
  ## Downloading source files (drawings, documents, specs, submittals, RFIs)
58
62
 
59
- The retrieval tools return **extracted text**, which is authoritative for schedules, notes, and spec paragraphs — but cannot answer spatial/visual questions (routing, clearances, what a plan view actually shows) and never carries the original file. Every entity has a download command, and **each accepts its `sb://` citation URL verbatim** (as returned by issues, search, and tool results — any `#page=`/`#nodeId=` fragment is ignored) or a bare UUID:
63
+ The retrieval tools return **extracted text**, which is authoritative for schedules, notes, and spec paragraphs — but cannot answer spatial/visual questions (routing, clearances, what a plan view actually shows) and never carries the original file. Every entity has a download command, and **each accepts its returned Specset `/go` link verbatim** (citation focus parameters are ignored for downloads) or a bare UUID:
60
64
 
61
- | Entity | Command | Also accepts | Formats / options |
62
- | -------------- | ------------------------------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
63
- | Drawing sheets | `specset drawings download 'sb://drawing/<uuid>'` | sheet number + `--project` | `--format image` (rendered PNG, default), `pdf` (single sheet), `file` (whole set) |
64
- | Documents | `specset docs download 'sb://doc/<uuid>'` | | also covers RFI attachments and closeout documents |
65
- | Spec sections | `specset specs download 'sb://spec/<uuid>'` | section number (e.g. `'23 31 19'`) + `--project` | per-section PDF slice (default), `--asset book` (whole source spec file) |
66
- | Submittals | `specset submittals download 'sb://sub/<uuid>'` | | compiled package (default when present); `--list` shows the asset inventory; `--asset attachment --index 2`, `--asset attachment --all` |
67
- | RFIs | `specset rfis download 'sb://rfi/<uuid>'` | | question + response attachments; `--list`, `--all` |
68
- | File resources | `specset files download 'sb://file/<uuid>'` | | escape hatch when you already hold an `sb://file` id |
65
+ | Entity | Command | Also accepts | Formats / options |
66
+ | -------------- | ----------------------------------------------------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
67
+ | Drawing sheets | `specset drawings download 'https://app.specbook.ai/go/drawing/<uuid>'` | sheet number + `--project` | `--format image` (rendered PNG, default), `pdf` (single sheet), `file` (whole set) |
68
+ | Documents | `specset docs download 'https://app.specbook.ai/go/doc/<uuid>'` | | also covers RFI attachments and closeout documents |
69
+ | Spec sections | `specset specs download 'https://app.specbook.ai/go/spec/<uuid>'` | section number (e.g. `'23 31 19'`) + `--project` | per-section PDF slice (default), `--asset book` (whole source spec file) |
70
+ | Submittals | `specset submittals download 'https://app.specbook.ai/go/sub/<uuid>'` | | compiled package (default when present); `--list` shows the asset inventory; `--asset attachment --index 2`, `--asset attachment --all` |
71
+ | RFIs | `specset rfis download 'https://app.specbook.ai/go/rfi/<uuid>'` | | question + response attachments; `--list`, `--all` |
72
+ | File resources | `specset files download 'https://app.specbook.ai/go/file/<uuid>'` | | escape hatch for a returned file source link |
69
73
 
70
74
  All commands support `--json` (structured `{files: [{path, bytes, ...}]}` output) and `--out` (file path, or directory for multi-file downloads). A citation passed to the wrong command errors with the right one to use.
71
75
 
76
+ `drawings download` also accepts `--org <slug|id>` to pin the source organization when parallel sessions might change the active organization, for example `specset drawings download P2.120 --project <id> --org specbook --host <host> --format pdf`.
77
+
78
+ To inspect an existing detail crop, add `--node <shortId|UUID>`, for example `specset drawings download <sheet-ref> --node d6 --format image --out detail.png`. Use `--format pdf` for the saved crop PDF. This downloads the current revision's stored crop without regenerating it; missing nodes or crops return an error. Node crops do not support `--format file`. JSON output adds the resolved `nodeId` to the normal sheet download metadata.
79
+
80
+ Its JSON result includes `sheetId` and `revisionId` for the downloaded source. Compare the revision with any previously retrieved content before using that content's coordinates to crop the download.
81
+
72
82
  Typical loop for drawings: search or `getDrawingSheetContent` to find the sheet → hit a visual question the text can't settle → `drawings download` → read the PNG to inspect the geometry.
73
83
 
84
+ ### Drawn elements: what a drawing view prints, with positions
85
+
86
+ Before downloading a plan to read a tag or a value off it, check the sheet's **drawn elements**: every printed string on each Drawing node with a 0–1000 box on the node's crop (the ledger), and the tags, runs, connections, cross-references, and printed limits typed from those strings. Each typed element cites ledger rows (`d1a12` = row 12 of node `d1`), so the printed text and its box are always the row's.
87
+
88
+ ```bash
89
+ specset drawings elements show 'https://app.specbook.ai/go/drawing/<uuid>' # per node: read/typing status, counts, tags, runs, connections, references, limits, keynotes
90
+ specset drawings elements show E6.00 --project <id> --node d1 --grep 800AT # rows and elements whose text contains 800AT (implies --rows)
91
+ specset drawings elements show E6.00 --project <id> --rows --json # every row with kind, box, grid cell, rotation, cloud/revision flags
92
+ ```
93
+
94
+ Read the status line first. A successful ledger read is evidence of printed text; absence claims also need the applicable completeness, recall, revision-cloud and source-coverage gates. Partial reads or unchecked coverage need visual confirmation. A version match alone does not mean a failed extraction succeeded.
95
+
96
+ Graph tools are automatically available with `--project` for eligible projects (every current drawing sheet uses extraction version 5 or newer; empty projects also qualify). Graphs refresh automatically. To request an immediate rebuild from existing extracted content:
97
+
98
+ ```bash
99
+ specset drawings build-graph --project <id> --wait --timeout 1800 --host <host> --json
100
+ ```
101
+
102
+ Omit `--wait` to return after requesting the build. Waiting confirms a newly persisted graph snapshot, not complete ingestion or review readiness; inspect the returned statistics and `getDrawingGraphOverview` for stale nodes and bundles before reviewing. The server build continues after a timeout, so inspect the overview before requesting another build. This does not reprocess drawings. The command requires the existing `resolveProjectDrawingGraph` and `projectDrawingGraph` server API; it and these instructions ride the next CLI release.
103
+
104
+ Use `getDrawingGraphOverview` to discover bundle keys, `getCoordinationBundle` for their views, `traverseDrawingReferences` for callout links, and `findDrawingGraphElements` for labeled, schedule-derived assets and rooms. For graphical devices, including unlabeled glyphs, use the candidate symbol lookup when ingestion and a graph rebuild have populated it:
105
+
106
+ ```bash
107
+ specset tools run findDrawingGraphSymbols --project <id> --host <host> \
108
+ -F canonicalTypes='["LightFixture","Sprinkler"]' -F sheetNumber=A5.01 -F limit=20
109
+ ```
110
+
111
+ It returns source-linked boxes and their supporting legend definitions. You can also filter by `drawingArea`, `nodeId`, or a `scopeKey` returned by `getDrawingGraphOverview`; follow `nextOffset` when `hasMore` is true. These are incomplete candidate observations: zero results do not establish absence, matching types do not link devices across views, and returned counts are not verified physical totals. Confirm an issue-bearing interpretation by downloading and inspecting the source drawing with `specset drawings download <returned-link>`. The in-app visual analysis tool `examineDrawingSheets` is not exposed to external callers.
112
+
74
113
  ## MCP servers (local and hosted)
75
114
 
76
115
  The same server-side tool registry is available through two transports:
77
116
 
78
- - `specset mcp` is the local stdio transport for Claude Code, Codex, and other clients with shell access. It reuses the CLI login and active organization.
117
+ - `specset mcp` is the local stdio transport for Claude Code, Codex, and other clients with shell access. It reuses the CLI login. Pass `--org <slug|id>` to pin the organization, or use the selected org / sole membership on the chosen host.
79
118
  - `https://<specset-host>/mcp` is the stateless Streamable HTTP transport for hosted MCP clients. Its OAuth 2.1 consent flow selects an organization and binds it into the grant, so hosted clients must not put `orgId` in the connection URL. Add `projectId=<project-id>` to pin project scope.
80
119
  - First-party clients may instead supply a Specset session bearer token and select the organization with `x-org-id` (or the legacy `orgId` query parameter).
81
120
 
@@ -84,8 +123,8 @@ Register the local transport once and the client can call the tools directly:
84
123
  ```bash
85
124
  # Claude Code
86
125
  claude mcp add specset -- specset mcp
87
- # Optionally pin a project and/or host:
88
- claude mcp add specset -- specset mcp --project <projectId> --host https://app.specbook.ai
126
+ # Optionally pin organization, project and host:
127
+ claude mcp add specset -- specset mcp --org <slug> --project <projectId> --host https://app.specbook.ai
89
128
 
90
129
  # Codex
91
130
  codex mcp add specset -- specset mcp
@@ -99,6 +138,6 @@ Notes:
99
138
  - The hosted transport additionally exposes `uploadFile` (OpenAI host file parameters, streamed into Specset storage) and `getFileDownload` (an MCP resource link backed by a short-lived signed URL). The underlying retrieval tools are still the same allowlisted registry used by stdio.
100
139
  - The hosted transport advertises standards-compliant MCP OAuth 2.1 protected-resource and authorization-server metadata. It supports Client ID Metadata Documents, PKCE, resource/audience binding, scoped tools, short-lived access tokens, and rotating refresh tokens.
101
140
 
102
- ## Stability
141
+ ## Scripting
103
142
 
104
- This surface is experimental — tool names and input schemas may change. For automation you need to keep stable, prefer the typed `search` / `quickSearch` GraphQL queries in the `specset-search` skill.
143
+ Tools are discovered at runtime (`specset tools list`, MCP `tools/list`), and their descriptions and inputs are tuned for agents. For scripts that depend on a fixed response shape, use the typed `search` / `quickSearch` GraphQL queries in the `specset-search` skill.