@specset/cli 1.0.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.
- package/README.md +49 -2
- package/THIRD_PARTY_NOTICES.md +7 -1
- package/dist/main.js +39759 -12065
- package/package.json +7 -3
- package/plugin/specset/.claude-plugin/plugin.json +1 -1
- package/plugin/specset/.codex-plugin/plugin.json +6 -3
- package/plugin/specset/assets/icon.png +0 -0
- package/plugin/specset/skills/specset/SKILL.md +13 -2
- package/plugin/specset/skills/specset-admin/SKILL.md +21 -7
- package/plugin/specset/skills/specset-agent/SKILL.md +136 -1
- package/plugin/specset/skills/specset-closeout/SKILL.md +156 -2
- package/plugin/specset/skills/specset-issues/SKILL.md +27 -0
- package/plugin/specset/skills/specset-projects/SKILL.md +42 -17
- package/plugin/specset/skills/specset-submittals/SKILL.md +4 -2
- package/plugin/specset/skills/specset-tools/SKILL.md +44 -6
- package/skills/specset/SKILL.md +13 -2
- package/skills/specset-admin/SKILL.md +21 -7
- package/skills/specset-agent/SKILL.md +136 -1
- package/skills/specset-closeout/SKILL.md +156 -2
- package/skills/specset-issues/SKILL.md +27 -0
- package/skills/specset-projects/SKILL.md +42 -17
- package/skills/specset-submittals/SKILL.md +4 -2
- package/skills/specset-tools/SKILL.md +44 -6
|
@@ -164,9 +164,163 @@ Other lifecycle operations:
|
|
|
164
164
|
|
|
165
165
|
## Entity Documents and Documentation
|
|
166
166
|
|
|
167
|
-
Location, Product, Company, System, and Warranty link project Documents through entity-specific role-tagged pivots. Read `<entity>Documents(<entity>Id)`, then call `set<Entity>DocumentRoles(<entity>Id, documentId, roles)` after introspecting that entity's role enum.
|
|
167
|
+
Asset, Location, Product, Company, System, and Warranty link project Documents through entity-specific role-tagged pivots. Read `<entity>Documents(<entity>Id)`, then call `set<Entity>DocumentRoles(<entity>Id, documentId, roles)` after introspecting that entity's role enum (`AssetDocumentRole`, `ProductDocumentRole`, `SystemDocumentRole`, `LocationDocumentRole`, `CompanyDocumentRole`, `WarrantyDocumentRole`). The roles array is replaced atomically; an empty role list removes the pivot and may delete the underlying Document when it becomes orphaned. Asset also exposes `deleteAssetDocument(id)`.
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
Attaching a new file is a three-step flow — the same Document can then be linked to several entities (a family IOM shared by every product in the family):
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
CLOUD_FILE=$(specset files upload ./aaon-rn-iom.pdf --type application/pdf --json | jq -r .id)
|
|
173
|
+
specset api --query "mutation { createDocumentsFromCloudFiles(cloudFileIds: [\"$CLOUD_FILE\"], projectId: \"<project-id>\") { id title } }"
|
|
174
|
+
specset api --query 'mutation { updateDocument(id: "<document-id>", title: "AAON RN Series — IOM") { id } }' # title drives lists and PDF bookmarks; the default is the filename
|
|
175
|
+
specset api --query 'mutation { setProductDocumentRoles(productId: "<product-id>", documentId: "<document-id>", roles: [OperationManual, MaintenanceManual]) { id } }'
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Existing project Documents work too — a submittal attachment's `document { id }` (from `paginatedSubmittals … attachments { document { id title } }`) can be linked directly as `SubmittalPackage`/`Datasheet`; the only check is that the Document belongs to the same project. To bind a slice of a large file, `extractPagesFromFileResource(id: <fileResourceId>, pages: [3, 4, 5])` returns a new CloudFile to feed into `createDocumentsFromCloudFiles`. Only PDF files merge into the O&M package export; images and other types are listed as references.
|
|
179
|
+
|
|
180
|
+
Asset, Location, Product, Company, and System also have markdown documentation blocks. `update<Entity>Documentation(id, markdown)` replaces the block; `mark<Entity>DocumentationComplete(id)` attests that it is current. Any later create/update/link on the entity (a new document pivot, a warranty document, a field edit) marks the documentation stale again, so when seeding a graph write documentation **last**. Calling `mark<Entity>DocumentationComplete` with an empty block sets the state to `NotApplicable`, which the package readiness report accepts — use it for entities that don't warrant prose rather than writing filler.
|
|
181
|
+
|
|
182
|
+
### Writing documentation that reads well in the O&M package export
|
|
183
|
+
|
|
184
|
+
The rules below are the same ones the in-app documentation agent follows (they are one shared block; a test keeps this copy in sync).
|
|
185
|
+
|
|
186
|
+
### Where Documentation Renders
|
|
187
|
+
|
|
188
|
+
The documentation block renders on the entity's show page and in the compiled O&M closeout package PDF — a formal handover manual the owner's facilities team keeps for decades. The manual already prints the following from structured data, so documentation never restates it:
|
|
189
|
+
|
|
190
|
+
- Identity: tag, serial number, status, install and commissioning dates, quantity, location path, manufacturer, model, spec section, classification, data-package tier.
|
|
191
|
+
- Warranties: kind, start and expiration dates, duration, claims contact and the terms text.
|
|
192
|
+
- Maintenance schedule: every plan, procedure, frequency, craft and estimated hours, built from the maintenance plan records.
|
|
193
|
+
- Spare parts: name, SKU, manufacturer part number, quantity and vendor, from the part records.
|
|
194
|
+
- Contacts: the responsible company with phone and email, plus a per-system contacts rollup.
|
|
195
|
+
- Linked documents: every datasheet, manual, warranty and report, listed and bound directly behind the entity's page.
|
|
196
|
+
|
|
197
|
+
### What to Write
|
|
198
|
+
|
|
199
|
+
Spend the narrative on what tables cannot say: sequences of operation with real setpoints, startup and shutdown, seasonal and emergency procedures, troubleshooting, safety warnings, cross-system interfaces, and callouts where sources conflict. Describe the equipment, not the records — state how it works and how it is cared for, and fold genuine unknowns into one short "Open Items" list, one line each, without citations. A short block with two real sections beats a full template of filler: omit every section the sources don't genuinely cover, and leaving the block blank is a valid outcome for an entity with nothing to add.
|
|
200
|
+
|
|
201
|
+
Write for the building operator in plain language. Paraphrase manual procedures as proper markdown lists, and fix concatenation artifacts (double periods, misspelled manufacturer names) from sources.
|
|
202
|
+
|
|
203
|
+
Keep the block free of what the manual already prints and of anything that goes stale:
|
|
204
|
+
|
|
205
|
+
- No warranty terms or dates in prose, no frequency lists or task inventories, no tag/serial/model/quantity dossiers, no contractor names or phone numbers, and no parts tables pasted from manuals — replacement-parts data belongs in part records.
|
|
206
|
+
- No claims about the state of the records ("no dates are populated", "this task is recorded on the checklist") — they end up contradicting the printed tables.
|
|
207
|
+
- No restatement of the entity's `description` field as the opening — both print in sequence.
|
|
208
|
+
- No internal vocabulary ("portal", "normalized", "occurrence basis", "identity guard", "MaintenanceTask", "sourceMarkdown"), entity UUIDs, or extraction and slug references.
|
|
209
|
+
- No all-caps sentences or blockquote dumps of manual text, and no sections whose only content is "not established in reviewed source" or "see the linked manual".
|
|
210
|
+
|
|
211
|
+
### Citations
|
|
212
|
+
|
|
213
|
+
Citations are clickable in the app and plain text in the printed manual, so keep them sparse and short: at most one per section, placed at the end of the claim it supports, as a markdown link whose display text is a short label such as "Siemens O&M p. 712" or "Warranty Table p. 5". Use citation URLs exactly as returned by the tools. The entity's bound-documents list already anchors provenance, so there are no per-sentence citations, multi-citation parentheticals, full source filenames, paragraph numbers, spreadsheet cell references, or dedicated "Source:" lines (print strips those).
|
|
214
|
+
|
|
215
|
+
### Headings
|
|
216
|
+
|
|
217
|
+
The entity name renders as the page title, the block is embedded under a "Documentation" heading on the show page, and it may be re-rendered inside a parent entity's hierarchical view, so heading levels must compose:
|
|
218
|
+
|
|
219
|
+
- Top-level sections use `##`; sub-sections use `###`, then `####`, without skipping levels.
|
|
220
|
+
- Begin with the first content section (for example `## Description`). The entity's own name is never a heading and `#` is never used — that level is the page title, and a leading H1 matching the entity name is suppressed in print.
|
|
221
|
+
- Keep section names consistent with the templates below so sibling entities render with the same structure.
|
|
222
|
+
|
|
223
|
+
### Section Templates
|
|
224
|
+
|
|
225
|
+
Use these section orderings with the operator-facing names shown; most entities warrant only one to three of them.
|
|
226
|
+
|
|
227
|
+
**Product** — the canonical home for manufacturer operating knowledge. A product with any linked submittal, datasheet, manual or warranty document gets a block; only a product with no linked source documents is left blank. Location and system blocks may roll product knowledge up but never replace it.
|
|
228
|
+
|
|
229
|
+
```markdown
|
|
230
|
+
## Description (1-3 sentences: what it is and its role — not metadata)
|
|
231
|
+
## Operation (sequence of operation, setpoints, modes, interlocks)
|
|
232
|
+
## Routine Maintenance (procedure steps and precautions — never frequencies; the schedule table prints those)
|
|
233
|
+
## Troubleshooting
|
|
234
|
+
## Safety
|
|
235
|
+
## Open Items
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**System** — the system in its own words, spanning multiple products. A parent system covers only what is true of the whole (shared operation, shared safety): the manual prints the subsystems list and rolls up schedules, warranties and contacts, so content common to sibling systems lives once on the parent and each child gets at most one sentence of scope.
|
|
239
|
+
|
|
240
|
+
```markdown
|
|
241
|
+
## Description (what the system is and its boundary, 2-4 sentences)
|
|
242
|
+
## Sequence of Operation
|
|
243
|
+
## Interfaces (only real cross-system relationships: what feeds, releases, or controls what)
|
|
244
|
+
## Seasonal & Emergency Procedures
|
|
245
|
+
## Troubleshooting
|
|
246
|
+
## Safety
|
|
247
|
+
## Open Items
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Location** — building or area overview.
|
|
251
|
+
|
|
252
|
+
```markdown
|
|
253
|
+
## Description
|
|
254
|
+
## Access & Safety
|
|
255
|
+
## Open Items
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Asset** — installation-specific facts only; most assets need very little.
|
|
259
|
+
|
|
260
|
+
```markdown
|
|
261
|
+
## As-Installed Configuration (field settings, orientations, connections not captured by structured fields)
|
|
262
|
+
## Commissioning Notes
|
|
263
|
+
## Open Items
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Company** — only what the contacts block cannot carry.
|
|
267
|
+
|
|
268
|
+
```markdown
|
|
269
|
+
## Escalation
|
|
270
|
+
## Supplier Portal
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Example (Product)
|
|
274
|
+
|
|
275
|
+
```markdown
|
|
276
|
+
## Description
|
|
277
|
+
Passive rubber check valves preventing backflow from rivers, oceans, and storm water into outfall lines.
|
|
278
|
+
|
|
279
|
+
## Operation
|
|
280
|
+
Flow opens the bill section; back-pressure closes it. No power or operator action required. Do not exceed 25 psi back-pressure [Manual p. 3](sb://doc/...).
|
|
281
|
+
|
|
282
|
+
## Routine Maintenance
|
|
283
|
+
1. Clear debris from the bill opening.
|
|
284
|
+
2. Inspect the elastomer for cuts or abrasion; replace on any through-cut.
|
|
285
|
+
|
|
286
|
+
## Troubleshooting
|
|
287
|
+
Standing water upstream usually means debris is holding the bill open — clear before assuming valve failure.
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Parts and Meter Readings
|
|
291
|
+
|
|
292
|
+
`createPart(input: { projectId, name, sku, manufacturerPartNumber, unit, quantity, minQuantity, maxQuantity, unitCost, stocked, bin, vendorId, assetLinks: [{ assetId, quantity }] })` creates a stocked part with its per-asset quantities; `createPartMovement(input: { partId, quantity, note })` records receipts (positive) and consumption (negative), and `countedQuantity` records a cycle count. Read with `paginatedParts(projectId, filters)`.
|
|
293
|
+
|
|
294
|
+
`logMeterReading(assetId, unit: Hours|Cycles, value, readAt)` records a runtime or cycle reading; meter-triggered plan tiers (`meterUnit`/`meterThreshold`) generate work from these. `meterReadings(assetId, unit, limit)` lists them.
|
|
295
|
+
|
|
296
|
+
## Closeout Packages (O&M manual export)
|
|
297
|
+
|
|
298
|
+
A closeout package compiles the graph into one bookmarked PDF: front matter (cover, directory, warranty log, hyperlinked TOC), a slip sheet and overview per system (or location), a data page per asset, and every linked PDF document bound behind its owner (each unique file once). Scope is `Project` (everything), `Systems`, `Assets`, or `Locations` with `targetIds`; `orderingAxis` is `System` (default) or `Location`.
|
|
299
|
+
|
|
300
|
+
Check readiness first — it is deterministic and the same builder the compile uses, so a clean report means a clean manual:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
specset api --query '{ closeoutPackageReadiness(projectId: "<project-id>", scopeKind: Project) { warningCount warnings } }'
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Warning kinds and how to clear them: `DocumentationMissing`/`DocumentationOutdated` (write or mark documentation complete on the named Asset/Product/System/Location), `AssetFieldMissing` (serial number or install date), `WarrantyMissing` (every asset needs at least one Warranty), `ProductManualMissing` (each Product needs an `OperationManual` or `MaintenanceManual` document), `PlanWithoutProcedure` (a plan with no tiers), `AttachmentNotMergeable` (non-PDF), `TargetDeleted`. `EmptyScope` blocks creation.
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
specset api --query 'mutation { createCloseoutPackageExport(input: { projectId: "<project-id>", scopeKind: Project, orderingAxis: System, includeAttachments: true, title: "… O&M Manual" }) { id workflow { status } } }'
|
|
310
|
+
specset api --query '{ closeoutPackageExport(id: "<export-id>") { completedAt warnings workflow { status progress error } fileResource { id name } } }'
|
|
311
|
+
specset files download <file-resource-id> --out manual.pdf # once workflow.status is Completed
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
`paginatedCloseoutPackageExports(projectId)` lists prior exports; exports are immutable records — regenerate by creating a new one; `deleteCloseoutPackageExport(id)` removes one and its file. In the app the same flow lives under the project's Closeout → Packages page.
|
|
315
|
+
|
|
316
|
+
## Enabling closeout
|
|
317
|
+
|
|
318
|
+
`CloseoutAuthService.isCloseoutActive` requires the org SKU **and** (unless the org is in `fmMode`) the project toggle. Both are superadmin operations; `updateOrg(skus)` replaces the whole SKU object, so read the current flags and resend them:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
specset api --query '{ org(id: "<org-id>") { skus { closeout fmMode dailyLog scheduling estimation agentSessions agentSkills customAgents whitelabel modelRoutingV2 } } }'
|
|
322
|
+
specset api --query 'mutation { updateOrg(id: "<org-id>", skus: { closeout: true, dailyLog: true, scheduling: true }) { id } updateProject(id: "<project-id>", toolSettings: { closeout: true }) { id } }'
|
|
323
|
+
```
|
|
170
324
|
|
|
171
325
|
## Dedup / Re-pointing
|
|
172
326
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: specset-issues
|
|
3
|
+
description: Use when working with a Specset project's design-review issues from the CLI — listing the queue by severity, tier, or verification state, and reading each issue's verdict.
|
|
4
|
+
allowed-tools: Bash Read AskUserQuestion
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Specset Issues
|
|
8
|
+
|
|
9
|
+
Design reviews (Design Review, Drawing Review, Design Quality Review, Project Review) and issue-finding skills file **issues** on a project. Each issue can be **verified** by an adversarial agent that re-reads the cited sheets and sections and records a verdict — `Confirmed` or `Rejected` — with a short justification. New review issues are verified automatically; skill-run issues, issues filed before verification existed, and issues whose runs ended without a verdict are verified on demand.
|
|
10
|
+
|
|
11
|
+
## Reading the queue
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
specset issues list --project <projectId> # active, non-Cleanup issues
|
|
15
|
+
specset issues list --project <projectId> --severity High,Medium --notVerified --limit 500
|
|
16
|
+
specset issues list --project <projectId> --thread <reviewThreadId> --json # one review's findings
|
|
17
|
+
specset issues list --project <projectId> --thread <runThreadId> --org <slug> # a skill run, by the id agent chat printed
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
- `--severity` takes a comma list (`High`, `Medium`, `Low`); `--notVerified` keeps only issues with no verdict; `--archived` switches to the archived set.
|
|
21
|
+
- `--thread` matches the thread and every review thread under it: a skill's issues belong to its delegated review, so the run id `specset agent chat` prints finds them directly. `--org` pins the organization like the other commands.
|
|
22
|
+
- Cleanup-tier issues (real but self-resolving, kept out of the review queue) are excluded unless you pass `--includeCleanup` — the same rule the app's default queue uses.
|
|
23
|
+
- The table shows `#number severity tier verdict title`; `verdict` is `Confirmed`, `Rejected`, `verifying` (run in flight) or `unverified`. `--json` returns the full rows including the originating review thread.
|
|
24
|
+
|
|
25
|
+
## Verification
|
|
26
|
+
|
|
27
|
+
Verdicts come from the app's own verification runs: new review issues are verified automatically, and a member can start verification for an individual issue from the issue in the app. `specset issues list` shows the verdict on every row (`--notVerified` to find the ones still waiting).
|
|
@@ -8,6 +8,10 @@ allowed-tools: Bash Read AskUserQuestion
|
|
|
8
8
|
|
|
9
9
|
This skill mutates data — confirm the project name and which files belong to it before creating anything. Inline enums, ints, lists, and input objects in the operation text (`-F` is strings-only; Variable Limitations and Schema Discovery live in the `specset` skill).
|
|
10
10
|
|
|
11
|
+
## Find a project
|
|
12
|
+
|
|
13
|
+
Use `specset projects list --json` to list the active organization's projects with IDs and links. `--org <slug|id>` pins another organization, `--limit 20` bounds output, and `--archived` lists archived projects. Pass a returned ID or link to other project commands.
|
|
14
|
+
|
|
11
15
|
## Reading Projects
|
|
12
16
|
|
|
13
17
|
```graphql
|
|
@@ -20,17 +24,17 @@ project(id: ID!): Project!
|
|
|
20
24
|
|
|
21
25
|
## Creating a Project
|
|
22
26
|
|
|
23
|
-
`createProject` does **not** add the creator as a project member, so the new project won't appear in the default `projects` list — fetch it by `project(id)
|
|
27
|
+
`createProject` does **not** add the creator as a project member, so the new project won't appear in the default `projects` list until someone adds them — fetch it by `project(id)`. The `createProject` mutation takes `userIds` and `teamIds` to add members in the same call; `specset projects create` doesn't, so add them as a second step.
|
|
24
28
|
|
|
25
|
-
1. Create it:
|
|
29
|
+
1. Create it with the project command. New projects automatically support drawing graphs; no opt-in is required:
|
|
26
30
|
|
|
27
31
|
```bash
|
|
28
|
-
specset
|
|
29
|
-
createProject(orgId: $orgId, name: $name) { id name }
|
|
30
|
-
}' -F orgId=<org-id> -F name='Riverside Medical Center'
|
|
32
|
+
specset projects create 'Riverside Medical Center' --json
|
|
31
33
|
```
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
Select the active organization first with `specset org use <slug>`. Pass `--host <url>` to both commands when targeting a specific deployment. JSON output includes `id`, `name`, and `drawingGraphEnabled`. Existing projects qualify when every current sheet supports graph resolution (node version 5 or later); ledger failures do not disable graphs.
|
|
36
|
+
|
|
37
|
+
2. Get your own user id with `{ me { id } }`, then add yourself (and anyone else the user names) as a member. `role` is an optional `OrgMemberTeamRole` enum — `Member`, `Manager`, or `Admin` — inlined when specified. To add several people or whole teams at once, use `addProjectMembers(projectId: ID!, userIds: [ID!], teamIds: [ID!])` (inline the lists); a team puts everyone on it on the project, and `teams(orgId)` lists them:
|
|
34
38
|
|
|
35
39
|
```bash
|
|
36
40
|
specset api --query 'mutation($projectId: ID!, $userId: ID!) {
|
|
@@ -38,27 +42,31 @@ specset api --query 'mutation($projectId: ID!, $userId: ID!) {
|
|
|
38
42
|
}' -F projectId=<project-id> -F userId=<user-id>
|
|
39
43
|
```
|
|
40
44
|
|
|
45
|
+
## Review Settings
|
|
46
|
+
|
|
47
|
+
Drawing graphs rebuild automatically as project inputs change. Automatic
|
|
48
|
+
verification of newly filed review issues is a platform setting managed by
|
|
49
|
+
Specset; it does not verify the existing queue. Project Review has no separate
|
|
50
|
+
project toggle; its availability in the app comes from the organization's
|
|
51
|
+
configured agents.
|
|
52
|
+
|
|
41
53
|
## Importing Documents
|
|
42
54
|
|
|
43
|
-
|
|
44
|
-
|
|
55
|
+
For an existing project, inspect drawing review readiness with `specset projects drawing-graph --project <id> --json`. Add `--rebuild` to queue resolution from already extracted drawing content; this does not start sheet extraction or element backfill. Re-run the command without mutation flags to inspect readiness after the background rebuild. Eligibility is automatic for new projects and existing projects whose current sheets are all at node version 5 or later. Pin `--host` and `--org` when targeting a particular deployment or organization.
|
|
56
|
+
|
|
57
|
+
Use the document-import command for local files; it uploads them, registers them on the project, and publishes the generated drawing/specification files automatically:
|
|
45
58
|
|
|
46
59
|
```bash
|
|
47
|
-
specset
|
|
48
|
-
|
|
49
|
-
projectId: $projectId
|
|
50
|
-
cloudFileIds: [$f1, $f2]
|
|
51
|
-
autoImport: true
|
|
52
|
-
}) { id totalCount completedCount failedCount }
|
|
53
|
-
}' -F projectId=<project-id> -F f1=<cloud-file-id> -F f2=<cloud-file-id>
|
|
60
|
+
specset projects add-docs --project <project-id> ./drawings.pdf ./specifications.pdf --json
|
|
61
|
+
specset projects ingest-status --project <project-id> --wait --timeout 1800 --json
|
|
54
62
|
```
|
|
55
63
|
|
|
56
|
-
|
|
64
|
+
`add-docs` returns upload metadata and the background bulk action immediately. `ingest-status --wait` follows processing and publication; omit `--wait` for a snapshot. Processing extracts each document's outline and content, indexes it for search, and splits it into candidate spec files and drawing files by page range. The status command checks workflow completion and file publication; use drawing-element or graph tools to inspect content quality.
|
|
57
65
|
|
|
58
66
|
### `autoImport`: publish automatically or curate
|
|
59
67
|
|
|
60
68
|
- `autoImport: true` — every generated spec/drawing file is classified and published into default sets automatically. Use when the user wants everything live immediately.
|
|
61
|
-
-
|
|
69
|
+
- Pass `--noAutoImport` to `add-docs` — files land **unpromoted** for manual curation below. Use when the user wants to control set titles, membership, or ordering. The raw `createProjectDocuments` API defaults to unpromoted when `autoImport` is omitted.
|
|
62
70
|
|
|
63
71
|
Ask the user when their intent is ambiguous — this choice changes what gets published. The input also supports folders: `parentFolderId` / `newFolderName` for flat imports, or `folderTree` + `files` to mirror a directory structure — introspect `CreateProjectDocumentsInput` for those shapes.
|
|
64
72
|
|
|
@@ -98,6 +106,21 @@ updateDrawingSetPrecedence(projectId: ID!, drawingSetIds: [ID!]!): [DrawingSet!]
|
|
|
98
106
|
|
|
99
107
|
4. Verify and summarize — query `project(id)` (not the membership-filtered `projects` list) with `specSets { id title }` and `drawingSets { id title }`, and report what was created.
|
|
100
108
|
|
|
109
|
+
## Downloading Project Material
|
|
110
|
+
|
|
111
|
+
`specset projects hydrate` pulls a project's source material into a local directory so an agent (or a person) can read the PDFs directly instead of fetching sections one at a time:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
specset projects hydrate <projectId|link> --out ./pier-romeo # specs/, drawings/, docs/
|
|
115
|
+
specset projects hydrate <projectId|link> --out ./pier-romeo --include specs,drawings
|
|
116
|
+
specset projects hydrate <projectId|link> --json # default --out: ~/Specset/<host>/<project-name>-<projectId>/
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- `specs/` holds one PDF per spec section (`<number> - <title>.pdf`), `drawings/` one PDF per drawing sheet (`<sheet> - <title>.pdf`, the rendered image for legacy sheets), and `docs/` the project's other documents (reports, permits, manuals). The spec book and drawing set PDFs themselves are not repeated under `docs/` — fetch a whole book with `specset specs download <ref> --asset book` when needed.
|
|
120
|
+
- Re-running is idempotent: files already present at the stored size are skipped, so run it again after new documents are processed to pick up only what changed.
|
|
121
|
+
- `--json` returns `{ projectId, out, files: [{ path, kind, ref, bytes, sha256 }], skipped, failures }`; `ref` is the public link of the source entity. **Cite that link, never the local path**, when reporting findings from a downloaded file.
|
|
122
|
+
- Large projects can be hundreds of files; start with `--include specs` when only the specifications matter. A non-zero exit means some downloads failed — re-run the same command to retry just those.
|
|
123
|
+
|
|
101
124
|
## Archiving and Deleting
|
|
102
125
|
|
|
103
126
|
- **Prefer `archiveProject(id: ID!)`** — reversible via `unarchiveProject(id: ID!)`. Archived projects drop out of default lists but keep all data.
|
|
@@ -108,3 +131,5 @@ updateDrawingSetPrecedence(projectId: ID!, drawingSetIds: [ID!]!): [DrawingSet!]
|
|
|
108
131
|
- Authorization error on a mutation — the user lacks that permission; the same rules as the UI apply. Surface the message, don't retry.
|
|
109
132
|
- A freshly created project "missing" from `projects` — that's the membership gotcha above, not a failure.
|
|
110
133
|
- A document reports a failed processing status on the BulkAction — report it to the user; re-uploading is their call.
|
|
134
|
+
|
|
135
|
+
Hydration records each file's Specset link, version id and checksum in `.specset/manifest.json`. Inside a local run's workspace (`specset agent serve` with **Native tools** on) the single `… download` commands record there too, and a version already present is not fetched again.
|
|
@@ -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
|
|
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(
|
|
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.
|
|
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
|
|
|
@@ -22,6 +22,7 @@ There are three tiers of Specset retrieval. Pick the lightest one that answers t
|
|
|
22
22
|
specset tools list
|
|
23
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.
|
|
@@ -55,6 +56,8 @@ Tool results expose clickable links shaped like `https://app.specbook.ai/go/spec
|
|
|
55
56
|
|
|
56
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.
|
|
57
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.
|
|
60
|
+
|
|
58
61
|
## Downloading source files (drawings, documents, specs, submittals, RFIs)
|
|
59
62
|
|
|
60
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:
|
|
@@ -70,13 +73,48 @@ The retrieval tools return **extracted text**, which is authoritative for schedu
|
|
|
70
73
|
|
|
71
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.
|
|
72
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
|
+
|
|
73
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.
|
|
74
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
|
+
|
|
75
113
|
## MCP servers (local and hosted)
|
|
76
114
|
|
|
77
115
|
The same server-side tool registry is available through two transports:
|
|
78
116
|
|
|
79
|
-
- `specset mcp` is the local stdio transport for Claude Code, Codex, and other clients with shell access. It reuses the CLI login
|
|
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.
|
|
80
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.
|
|
81
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).
|
|
82
120
|
|
|
@@ -85,8 +123,8 @@ Register the local transport once and the client can call the tools directly:
|
|
|
85
123
|
```bash
|
|
86
124
|
# Claude Code
|
|
87
125
|
claude mcp add specset -- specset mcp
|
|
88
|
-
# Optionally pin
|
|
89
|
-
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
|
|
90
128
|
|
|
91
129
|
# Codex
|
|
92
130
|
codex mcp add specset -- specset mcp
|
|
@@ -100,6 +138,6 @@ Notes:
|
|
|
100
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.
|
|
101
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.
|
|
102
140
|
|
|
103
|
-
##
|
|
141
|
+
## Scripting
|
|
104
142
|
|
|
105
|
-
|
|
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.
|