@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
|
@@ -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.
|
package/skills/specset/SKILL.md
CHANGED
|
@@ -31,13 +31,15 @@ This is the core skill — setup and mechanics only. Domain workflows live in si
|
|
|
31
31
|
|
|
32
32
|
Run this when the user installs or updates the skill/plugin, asks to get started with Specset, or when a command fails because the CLI is missing or unauthenticated. Every step is idempotent — skip any that's already satisfied.
|
|
33
33
|
|
|
34
|
-
1. **Install or update the CLI** (Node.js
|
|
35
|
-
2. **Authenticate** — check with `specset auth status`. If not logged in: `specset login` when a visible browser is available on this machine (tell the user to complete sign-in there while the command waits); `specset login --device` otherwise (SSH, containers, CI, remote/in-app sessions). Device login prints a code and a link (`https://<host>/device?code=XXXX-XXXX`) — show both to the user; the command completes once they approve. Codes expire after 15 minutes; rerun for a fresh one.
|
|
34
|
+
1. **Install or update the CLI** (Node.js 22+). Installing a skill/plugin does not upgrade the npm package. If `specset --version` is missing or older than `npm view @specset/cli version`, run `npm install -g @specset/cli@latest` (don't replace a source-linked development CLI whose version is newer than npm). After upgrading, refresh the skills with `specset skill install --target <claude|codex|chatgpt>`.
|
|
35
|
+
2. **Authenticate** — check with `specset auth status`. If not logged in: `specset login` when a visible browser is available on this machine (tell the user to complete sign-in there while the command waits); `specset login --device` otherwise (SSH, containers, CI, remote/in-app sessions). Device login prints a code and a link (`https://<host>/device?code=XXXX-XXXX`) — show both to the user; the command completes once they approve. Codes expire after 15 minutes; rerun for a fresh one. When any command answers `Session invalid`, run `specset login` (or `--device`) for that host again: it replaces the stored session the server no longer accepts. `specset logout` is only for switching accounts.
|
|
36
36
|
3. **Pick the active organization** (required for org-scoped queries): `specset org list`, then `specset org use <slug>`. If the user belongs to exactly one org, select it; otherwise ask which to use.
|
|
37
37
|
4. **Confirm** with `specset auth status`.
|
|
38
38
|
|
|
39
39
|
Credentials persist across sessions in `~/.config/specset/config.yml` (mode 0600) — setup only needs to happen once per machine.
|
|
40
40
|
|
|
41
|
+
If `specset auth status` reports an invalid session, run `specset logout`, then sign in again. Pin the same `--host` on both commands when using a development or non-default host; `login` does not replace an existing stored session.
|
|
42
|
+
|
|
41
43
|
## Running GraphQL
|
|
42
44
|
|
|
43
45
|
Use the `api` subcommand. It accepts the operation via `--query` or stdin, and string variables via `-F key=value` (repeatable). Output preserves the raw JSON GraphQL envelope (`{ data, errors }`) — non-zero exit on HTTP errors or `errors[]`.
|
|
@@ -59,6 +61,14 @@ query {
|
|
|
59
61
|
GQL
|
|
60
62
|
```
|
|
61
63
|
|
|
64
|
+
### Organization scope
|
|
65
|
+
|
|
66
|
+
Calls run in the active organization (`specset org use <slug>`). Pass `--org <slug|id>` to pin a different org for one call — required when the project belongs to another org, and safer in parallel sessions because the active org is shared config that another session can switch mid-task. `--noOrg` omits the org header entirely for global/superadmin operations; the two flags are mutually exclusive.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
specset api --org poettker --query '{ paginatedAssets(projectId: "…", limit: 5) { totalFilteredCount } }'
|
|
70
|
+
```
|
|
71
|
+
|
|
62
72
|
### Variable Limitations
|
|
63
73
|
|
|
64
74
|
`-F key=value` only sends **string** values. For non-string args (numbers, booleans, enums, input objects, lists), inline literals directly in the operation rather than parameterizing them. Reserve `-F` for IDs and plain strings.
|
|
@@ -116,5 +126,6 @@ Confirm with the user before executing mutations that create, update, or delete
|
|
|
116
126
|
|
|
117
127
|
## Troubleshooting
|
|
118
128
|
|
|
129
|
+
- A server/network failure while selecting the organization (for example HTTP 502) — check the pinned host and server availability, then retry the same command. This does not establish a login-policy failure.
|
|
119
130
|
- Auth, org, or missing-CLI errors (`command not found`, `Not logged in`, `No active organization selected`, login hangs) — run the matching First-Run Setup step above.
|
|
120
131
|
- A lookup by id returns `null` without an error — the record usually belongs to a different org than the active one; check `specset auth status` and switch with `specset org use <slug>`.
|
|
@@ -31,7 +31,7 @@ specset api --query 'query($orgId: ID!, $search: String) {
|
|
|
31
31
|
|
|
32
32
|
Manage them (all take the **membership** id from the queries above, not the user id):
|
|
33
33
|
|
|
34
|
-
- `updateOrgMember(id: ID!, role: ..., projectIds: [ID!])` — `role` is required even when unchanged, so resend the current role when only touching `projectIds`. `projectIds` scopes a Member to specific projects;
|
|
34
|
+
- `updateOrgMember(id: ID!, role: ..., projectIds: [ID!], teamIds: [ID!])` — `role` is required even when unchanged, so resend the current role when only touching `projectIds`. `projectIds` scopes a Member to specific projects (the projects they were added to themselves; ones they're on through a team come with the team); `teamIds` replaces their teams. Omit either to leave it alone. Adding or removing a project, or a team's projects, needs management permission in each of those projects.
|
|
35
35
|
- `approveOrgMember(id: ID!)` — activate a `PendingApproval` member.
|
|
36
36
|
- `deactivateOrgMember(id: ID!)` / `reactivateOrgMember(id: ID!)` — suspend and restore access. Deactivation is reversible and preserves history — prefer it over any form of member deletion.
|
|
37
37
|
|
|
@@ -41,17 +41,31 @@ specset api --query 'mutation($id: ID!) {
|
|
|
41
41
|
}' -F id=<org-member-id>
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
##
|
|
44
|
+
## Teams
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
A team is a named group of members. Assigning a team to a project puts everyone on it on that project, and changes to the team carry over to every project it's on. Teams don't carry a role: people keep their org role unless a project role is set on them.
|
|
47
|
+
|
|
48
|
+
- `teams(orgId: ID!)` — select `{ id name members { orgMember { user { email } } } projects { project { id name } } canManage }`.
|
|
49
|
+
- `createTeam(orgId: ID!, name: String!, userIds: [ID!], projectIds: [ID!])`, `updateTeam(id: ID!, name: String, userIds: [ID!], projectIds: [ID!])` (lists replace; assignments to archived projects stay), `deleteTeam(id: ID!)`.
|
|
50
|
+
- On a project: `projectTeams(projectId: ID!)`, `addProjectMembers(projectId: ID!, userIds: [ID!], teamIds: [ID!])`, `removeProjectTeam(id: ID!)` (takes the `ProjectTeam` id).
|
|
51
|
+
|
|
52
|
+
Changing a team needs org Manager or Admin and management permission in every project the team is on or will be on; `canManage` says whether you have it.
|
|
53
|
+
|
|
54
|
+
## Adding Users and Invites
|
|
55
|
+
|
|
56
|
+
Nobody joins an org on someone else's say-so. Both paths below leave the person with a pending invitation they must accept — in the app (existing Specset users see an invite badge), by registering through the invite link, or by signing in with the org's SSO. Until then an added user is an `Invited` member: visible in pickers and assignable, but with no access.
|
|
57
|
+
|
|
58
|
+
- `createOrgMember(orgId: ID!, email: String!, firstName: String!, lastName: String!, role: ..., projectIds: [ID!], teamIds: [ID!], sendInvite: Boolean)` — adds the person as an `Invited` seat right away so they can be assigned work before they've joined. `sendInvite: true` emails the invite link; existing Specset users get the in-app invitation either way. Returns the `OrgMember` (`status: Invited`).
|
|
59
|
+
- `createOrgInvite(orgId: ID!, email: String!, role: ..., projectIds: [ID!])` — invite-only (no seat until they accept; no `teamIds`, so add teams once they have a seat); also used to (re-)invite an existing `Invited` seat. `projectIds` (optional, inline the list) pre-scopes a Member to specific projects. Set `role` deliberately — don't default people to more access than they need. Share the returned `inviteUrl` if the email might not land.
|
|
60
|
+
- `orgInvites(orgId: ID!)` / `paginatedOrgInvites(orgId: ID!, first: Int, after: String)` — pending invites; select `{ id user { email } role inviteUrl }`.
|
|
48
61
|
- `updateOrgInvite(id: ID!, role: ..., projectIds: [ID!])` — `role` is required.
|
|
49
|
-
- `
|
|
62
|
+
- `resendOrgInvite(id: ID!)` — rotates the link and re-sends the email.
|
|
63
|
+
- `deleteOrgInvite(id: ID!)` — revoke a pending invite (an `Invited` seat stays, as "Not invited"; `deleteOrgMember` removes the seat).
|
|
50
64
|
|
|
51
65
|
```bash
|
|
52
66
|
specset api --query 'mutation($orgId: ID!, $email: String!) {
|
|
53
|
-
|
|
54
|
-
id email
|
|
67
|
+
createOrgMember(orgId: $orgId, email: $email, firstName: "Alex", lastName: "Rivera", role: Member, sendInvite: true) {
|
|
68
|
+
id status user { email }
|
|
55
69
|
}
|
|
56
70
|
}' -F orgId=<org-id> -F email=alex@example.com
|
|
57
71
|
```
|
|
@@ -29,22 +29,157 @@ specset agent chat --project <projectId> -m "What mechanical equipment is schedu
|
|
|
29
29
|
# Continue the same conversation (thread id is in the first response)
|
|
30
30
|
specset agent chat --thread <threadId> -m "Which of those have submittals?"
|
|
31
31
|
|
|
32
|
+
# Attach local files to a new conversation or a follow-up message
|
|
33
|
+
specset agent chat --project <projectId> --file "RFI template.pdf" \
|
|
34
|
+
-m "Use this template to draft the RFI."
|
|
35
|
+
|
|
32
36
|
# Review a past conversation
|
|
33
37
|
specset agent show <threadId>
|
|
38
|
+
|
|
39
|
+
# Download a generated document (artifact ids are included in agent show)
|
|
40
|
+
specset agent export <artifactId> --format docx --out ./filled-rfi.docx
|
|
41
|
+
specset agent export <artifactId> --format pdf --out ./filled-rfi.pdf
|
|
42
|
+
|
|
43
|
+
# Pin the host and organization when inspecting a local test run
|
|
44
|
+
specset agent show <threadId-or-link> --host https://app2.specset.dev --org <slug-or-id> --json
|
|
45
|
+
|
|
46
|
+
# Super-admin: inspect the current system prompt, tools, and model-input messages
|
|
47
|
+
specset agent inspect <threadId-or-link> --host https://app2.specset.dev --org <slug-or-id> --json
|
|
34
48
|
```
|
|
35
49
|
|
|
36
50
|
Use `--json` for machine-readable output (all commands accept it). Long-running questions may need `--timeout <seconds>` — document analysis can take a few minutes.
|
|
37
51
|
|
|
52
|
+
`--file <path>` uploads and attaches a file through the same processing flow as
|
|
53
|
+
the app. Repeat it for multiple attachments; PDF, Word, Excel and image MIME types
|
|
54
|
+
are inferred from the extension. It also works with `agent start` and with
|
|
55
|
+
`chat --thread` to attach files to an existing conversation. The upload belongs to
|
|
56
|
+
the thread's organization. Use `--detach` to return the thread id immediately
|
|
57
|
+
while the attachment processing and response continue.
|
|
58
|
+
|
|
59
|
+
`agent export` supports document artifacts in Word/PDF. Prepared templates retain
|
|
60
|
+
their original formatting; other documents are rebuilt from their saved markdown.
|
|
61
|
+
For documents edited in Pages, export in the app to preserve Pages layout,
|
|
62
|
+
headers, and notes. Other artifact types have their own export formats in the app.
|
|
63
|
+
A delegated draft has its own thread, so run `agent show` on the returned child
|
|
64
|
+
thread to find its artifact id.
|
|
65
|
+
|
|
38
66
|
Agent transcripts expose their source references as clickable `https://app.specbook.ai/go/...` links. Preserve the most relevant returned links as descriptive Markdown citations when relaying the answer to the user. Do not fabricate additional links from UUIDs. An identifier that is not an `https://` link (a thread-local short id or `doc:`-prefixed identifier) is internal — pass it back into commands verbatim, but never present it to the user as a clickable link. Both `--project` and `--thread` accept returned Specset links as well as UUIDs.
|
|
39
67
|
|
|
40
68
|
Find a project id first if you don't have one:
|
|
41
69
|
|
|
42
70
|
```bash
|
|
43
|
-
specset
|
|
71
|
+
specset projects list --json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Starting a Review Session Directly
|
|
75
|
+
|
|
76
|
+
Start a Quick Project Review investigation with an explicit brief and bounded
|
|
77
|
+
scope. Project Review remains a superadmin-only option in the agent picker;
|
|
78
|
+
shared organization and project access checks also apply.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
specset agent start --type ProjectReview --project <projectId> --noAutoApprovePlan \
|
|
82
|
+
--title "Building coordination pilot" \
|
|
83
|
+
-m "Review Building 720.1 at Quick effort for cross-discipline coordination problems. Prioritize the strongest leads and report what you did not examine."
|
|
84
|
+
specset agent show <threadId>
|
|
85
|
+
specset agent approve <threadId> --tool finalizePlan --wait --timeout 1800
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Pin the same `--host` on each command for a development deployment. Inspect the
|
|
89
|
+
short markdown plan before approving. Quick is the default: after approval, the
|
|
90
|
+
root investigates directly with drawing, graph, specification and document tools,
|
|
91
|
+
files issues, and reports examination limits. Standard and Deep use investigation
|
|
92
|
+
workers within the approved budget. All efforts use the agentic review route. Server step
|
|
93
|
+
backstops are not work targets or dollar caps; automatic issue verification follows
|
|
94
|
+
project policy and adds separate cost.
|
|
95
|
+
|
|
96
|
+
Drawing graph navigation is automatic for eligible projects. Use
|
|
97
|
+
`drawings build-graph --project <projectId> --wait` only for an explicit rebuild.
|
|
98
|
+
Inspect `getDrawingGraphOverview` bundles and quality flags before a benchmark;
|
|
99
|
+
building the graph does not reprocess stale source nodes. `--autoApprovePlan`
|
|
100
|
+
allows immediate execution when the brief is already approved.
|
|
101
|
+
`agent approve --deny --reason "…"` rejects a pending proposal for revision.
|
|
102
|
+
`agent stop <threadId>` cancels a running review and its descendants.
|
|
103
|
+
|
|
104
|
+
Long-running agents — Design Review, Drawing Review, Design Quality Review, Structured Review, Submittal Log — can be started as their own session without going through a Conversation thread. `specset agent start` creates the thread with the given `--type`, titles it, seeds it with your kickoff instructions, and returns immediately with the thread id; the run continues on the server.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
specset agent start --type DesignReview --project <projectId> \
|
|
108
|
+
--title "Building 720.1 - Design Review" --autoApprovePlan \
|
|
109
|
+
-m "Run a design review restricted to the Building 720.1 spec and drawing areas. Omit the master / no-area pass. Building 720.1's own specifications govern; Appendix A is a backup reference only."
|
|
110
|
+
|
|
111
|
+
specset agent show <threadId> # progress, transcript, findings so far
|
|
112
|
+
|
|
113
|
+
# A Drawing Review runs graph-planned coordination checks; select them up front.
|
|
114
|
+
specset agent start --type DrawingReview --project <projectId> \
|
|
115
|
+
--coordinationTaskTypes ElectricalDistribution,ArchitectureMepPenetrations \
|
|
116
|
+
--drawingArea "Building 720.1" --title "Building 720.1 - Coordination" \
|
|
117
|
+
-m "Coordinate the selected systems for Building 720.1."
|
|
44
118
|
```
|
|
45
119
|
|
|
120
|
+
- `--type` accepts any top-level agent type (`DesignReview`, `DrawingReview`, `DesignQualityReview`, `StructuredReview`, `SubmittalLog`, …). The kickoff message is the review's scope: name the building areas, disciplines, sections or sheets, what to exclude, and any special coordination checks — the same text a user would type when launching the review in the app.
|
|
121
|
+
- `--type DrawingReview` also needs `--coordinationTaskTypes` (`all`, or a comma-separated subset of the 16 families: `CeilingOverhead`, `EquipmentPowerControls`, `LifeSafetyEgress`, `ArchitectureStructureOpenings`, `ArchitectureMepPenetrations`, `StructuralMepInterfaces`, `EnvelopeWaterproofing`, `FireLifeSafetyProtection`, `CivilSiteUtilities`, `ElectricalDistribution`, `MechanicalSystemsContinuity`, `PlumbingSystemsContinuity`, `StructuralSystemsContinuity`, `FireSuppressionSystemsContinuity`, `FireAlarmEmergencyCommunications`, `TechnologySecurityCommunications`). The server refuses a Drawing Review whose first message carries no scope, and the scope cannot change afterwards, so these flags apply only to new threads. `--drawingArea` limits the review to one building-scoped drawing area, and `--noDrawingArea` limits it to the sheets that belong to no drawing area (the site-wide set; exclusive with `--drawingArea`); `--coordinationTaskIds` narrows it to exact graph task ids for a bounded pilot or rerun (ids must belong to the selected families and area). `--executionIntent` decides how earlier reviews' runs of the same tasks are treated: `Reuse` (the default) answers a task from another review's completed run while the drawings it read are unchanged and leaves Blocked or Failed tasks alone (reported as incomplete), `RetryIncomplete` also re-runs those, and `Fresh` ignores earlier runs. The project needs a current drawing graph (`drawingCoordinationReviewAvailability.graphState` is `Ready`); otherwise the review cannot start.
|
|
122
|
+
- `--debugTrace` writes the thread's agent transcript and drawing-coordination trace to the development server's `.local/debug` for an investigation. `--noDebugTrace` turns it off for a continued thread; omitting the flag preserves its setting. Both flags also work with `agent chat`.
|
|
123
|
+
- Local Drawing Review kickoff uses the same required `--coordinationTaskTypes` and optional `--coordinationTaskIds` / `--drawingArea` flags as `agent start`. Pass them with the first message to `agent serve`; an existing thread keeps its original scope.
|
|
124
|
+
- `--autoApprovePlan` skips plan sign-off. To inspect a plan before execution, pass `--noAutoApprovePlan`: this also disables the CLI's default blanket tool approval, so the session parks at `finalizePlan`. Approve it with `agent approve <threadId> --tool finalizePlan`. Omitting the flag preserves the existing plan setting, but blanket approval defaults on. `--isolateIssues` hides the project's pre-existing issues; `--noIsolateIssues` explicitly restores ordinary issue reads. `--reviewEffort Quick|Standard|Deep` sets a Project Review's effort: Quick investigates the strongest few leads on the root; Standard covers the brief within an approved worker budget; Deep covers the whole surveyed inventory. The plan states the expected worker count and estimated worker cost for approval. Omitting it keeps the thread's setting (Quick for a new thread).
|
|
125
|
+
- `--scanParallelism <n>` sets a positive integer thread override for concurrent scan/coordination tasks (superadmin only). It uses the server's protected settings mutation, preserves other settings, and persists when later messages omit the flag. Each scan reads it at startup; changing it does not resize an already-running scan. For a scoped drawing-review benchmark, add `--scanParallelism 8` to the `agent start` command above or to `agent chat --type DrawingReview --timeout 2400`; select at least eight tasks to exercise that limit. It does not change the shared default or the review's internal visual/admission limits.
|
|
126
|
+
- `--title` names the session in Agent Sessions. `agent start` is `agent chat --detach` for a new thread; use `chat --type … --timeout …` instead when you want to wait for a short run to finish.
|
|
127
|
+
|
|
46
128
|
## Notes
|
|
47
129
|
|
|
48
130
|
- Keep one thread per topic: follow-ups via `--thread` give the agent the prior context and produce better answers than fresh threads.
|
|
49
131
|
- The agent may propose changes (creating submittals, updating records) but those are applied through the Specset UI thread where the user approves them — CLI chat is best treated as read/analysis oriented. To make changes headlessly, use the mutations documented in the domain skills instead.
|
|
50
132
|
- The agent answers from the project you scope it to; double-check the `--project` id when results look unrelated.
|
|
133
|
+
|
|
134
|
+
For local drawing evaluations, add `--freshVisualReads` to `agent chat` or `agent start` to make every drawing examination a fresh response. It bypasses application response caching only in development; provider prefix discounts remain enabled. Use `--noFreshVisualReads` to restore normal behavior on that task.
|
|
135
|
+
|
|
136
|
+
For the local comparison-reader arm, add `--drawingComparisonModel OpenAI6Astra` alongside `--freshVisualReads`. Only multi-view, region, or subject-window drawing examinations use Astra medium; single-view overviews keep normal routing. `--drawingComparisonModel Auto` clears that override on an existing task. This switch is ignored in production and does not change planner or worker reasoning models.
|
|
137
|
+
|
|
138
|
+
## Run agent threads locally with your own Claude Code / Codex
|
|
139
|
+
|
|
140
|
+
`specset agent serve` connects this machine to Specset. A conversation switched to **Execute locally** (conversation Settings) runs its model calls through the user's own coding harness (Claude Code or Codex) instead of a cloud model, while Specset keeps the agent loop, its tools, approvals and the transcript. Nothing else changes for the user: the thread stays the record.
|
|
141
|
+
|
|
142
|
+
Install the Codex runtime once (Node.js 22 or newer); Claude uses the runtime bundled with the CLI:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
specset harness install codex # pins the native Codex runtime under ~/.specset/harness
|
|
146
|
+
specset harness list # what is installed, and which harness launched this shell
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Codex uses `CODEX_PATH` when set, then `codex` on PATH, then the managed runtime. Claude uses the bundled SDK runtime, then `claude` on PATH. Log in to the harness itself first (`claude auth login`, `codex login`); provider failures such as an exhausted usage limit end the affected run with one visible error.
|
|
150
|
+
|
|
151
|
+
**When the user asks to run a thread locally**, start the runner in the background so your own tool timeout does not cut it off, then check the thread:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
specset agent serve --host <deployment> --org <slug> --harness codex & # or --harness claude
|
|
155
|
+
specset agent show <thread link> # the transcript so far
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
What the harness spends is recorded on the thread as unbilled local usage (per model, priced for information only) and kept out of Specset's cost and credit figures.
|
|
159
|
+
|
|
160
|
+
### Native tools and the run workspace
|
|
161
|
+
|
|
162
|
+
Native tools are off by default: the harness only calls Specset functions, which the server authorizes and executes (approvals stay in the web app). Turn on **Native tools** in the conversation's Settings to let it also run shell commands and read, search or edit files. Each action is mirrored into the conversation as a local action card, and the thread's **Permissions** setting bounds what happens without asking: Read only, Accept edits, Auto (edits accepted, escalations reviewed) or Full access; for Codex these map to its sandbox (read-only, workspace-write, full access). Native sub-agents stay off; Specset's own sub-agent and fan-out tools run through the same machine.
|
|
163
|
+
|
|
164
|
+
Each run (a root thread and its children) works in one private directory under `--directory` (`~/.specset/personal-runs/<runner>/runs/<thread>/` by default) with `specs/`, `drawings/`, `docs/`, `inputs/` and `out/`. It starts empty. The `specset` CLI is logged in inside the session as the user for that host and organization, so the harness downloads what it needs: `specset specs download <ref> --out specs/`, `specset drawings download <ref> --format pdf --out drawings/`, `specset docs download <ref> --out docs/`, `specset files download <ref> --out inputs/`, or `specset projects hydrate <project> --out . --include specs,drawings,docs` for a whole project. `.specset/manifest.json` records each file's Specset link, version id and checksum; repeating a download is idempotent and replaces a stale version. Findings cite the Specset link, never the local path.
|
|
165
|
+
|
|
166
|
+
Files the harness writes under `out/` are the run's deliverables: after each turn that used native tools, and when the run ends, the runner uploads new or changed ones and attaches them to the root thread at their `out/…` path (a re-synced path replaces the earlier attachment). The workspace is removed once its run has ended (checked when the runner starts and stops and every ten minutes) or after seven untouched days; outputs that could not be attached keep the directory for a retry.
|
|
167
|
+
|
|
168
|
+
Sessions are ephemeral (`persistSession: false` for Claude, `ephemeral: true` for Codex): a restarted runner needs a new machine assignment and starts fresh sessions seeded from Specset's transcript. A lost native continuation fails visibly rather than replaying writes or switching to a cloud model. This is a personal runner executing project content as the local OS user, not an OS sandbox: use a separate account or host for untrusted content.
|
|
169
|
+
|
|
170
|
+
### Serve multiple local threads
|
|
171
|
+
|
|
172
|
+
Connect to an organization with `specset agent serve --host <host> --org <slug|id>`; no project or thread is required. Enable **Execute locally** in conversation Settings. A sole eligible connected runner automatically receives your queued local request; with multiple connected runners, choose **Machine** in Settings. The connection command disappears once a machine is connected. Completed, stopped, or expired runs offer **Start a new local run** above the composer; viewing them does not restart them. `--thread <id>` immediately assigns an existing root; `--message "Review electrical coordination" --type DrawingReview --coordinationTaskTypes ElectricalDistribution` creates a local root in the selected project. `--org <slug|id>` pins the org; otherwise the selected org or sole membership on that host is used. Omit `--project` for organization scope, or supply a comma-separated project allowlist. A new message-created thread requires exactly one project. Omit `--harness` to use that host’s saved default or its sole available native runtime; ambiguity requires an explicit choice. Claude uses the CLI’s bundled SDK runtime, then native `claude` on PATH. Codex uses `CODEX_PATH`, native `codex` on PATH, then the managed native runtime from `specset harness install codex`. Startup checks that runtime before registering. Run a separate `serve --host <deployment>` process for each dev worktree. Each process prints and pins its host/org/harness at startup; later CLI host/org changes cannot redirect it. Login, selected org, and harness defaults are stored per host; execution limits apply per runner. For a bounded smoke test, add `--stopAfterIssues 2`; the root counts issues across its children and stops that tree when the threshold is reached (an in-flight batch can exceed it). Only this signed-in user can assign work, and children inherit the same machine, project scope, deadline and thread budget.
|
|
173
|
+
|
|
174
|
+
`agent serve` uses server-owned orchestration: Temporal executes the agent and its tools, while model requests run through the connected machine. This includes generic drawing-coordination assessments, image inputs and structured output. The runner keeps a native session alive across each complete parallel tool batch and sends back the server's authorized results. All Specset approvals remain in the web app; native tools follow the thread's **Native tools** setting (see above) and native delegation stays off. Independent model requests use independent sessions. Claude uses `persistSession: false`; Codex uses `ephemeral: true`.
|
|
175
|
+
|
|
176
|
+
For an unattended kickoff, `--autoApprovePlan` skips the plan sign-off and `--autoApprove` approves Specset tools for that message (default off for `serve`). `--isolateIssues` ignores pre-existing project issues when planning a bounded test. The command prints the created or assigned thread link. File attachments and file tool results preserve bytes, MIME type and optional filename through the same transport. Claude receives raw PDFs; Codex receives server-rendered PDF page images, capped at 20 pages per request across all PDFs. Both support image inputs and UTF-8 text attachments. Other binary formats fail explicitly until a compatible reader or conversion is available.
|
|
177
|
+
|
|
178
|
+
Pin both `--host <deployment>` and `--org <slug>` when using `agent chat`, `agent start`, `agent show`, `agent inspect`, `agent approve` or `agent stop`; these overrides do not change the CLI’s saved selection.
|
|
179
|
+
|
|
180
|
+
The conversation's Settings lists the models the connected machine reported (Codex's catalog, Claude's supported models) and pins one per harness for the thread, plus a reasoning effort from that model's reported levels (agent steps only; helper calls keep the harness default); `--model` on the machine pins one for every job and shows as fixed there. `--concurrency` defaults to 5 and limits active model calls; tool and approval waits release their slot so even 1 can complete nested fan-out. `--maxThreads` defaults to 100 and `--maxRunSeconds` to 3600 per root authorization. `--model` is fixed on the machine. Specset’s `--autoApprove` message setting controls tool approval; the thread's Permissions setting bounds native tools when they are on. Ctrl-C revokes the registration and stops queued/running descendants. A restart needs a new assignment. A lost native continuation fails visibly rather than replaying writes or switching to a cloud model.
|
|
181
|
+
|
|
182
|
+
Harness tool callbacks can only wait for results supplied by the server. Each job receives private harness configuration and a minimal environment; with native tools on, that private home also holds a CLI login for the run's host and organization so `specset` works from the harness's shell. Claude shares the selected native credential store and its refresh lock. Codex uses an authentication-only native process to refresh the selected login, then supplies temporary access tokens to isolated inference sessions. Neither copies rotating refresh credentials into job homes. Settings, hooks, plugins and global MCP servers are excluded from inference sessions. Run `claude auth login` first if the harness reports authentication is required. It still runs as the local OS user, not inside an OS sandbox. Use a dedicated account or isolated host for untrusted project content; do not share this personal runner across users. This command requires the matching personal-runner and local-inference server APIs and ships in the next CLI release.
|
|
183
|
+
|
|
184
|
+
Use `specset agent runners list --json` to inspect your registrations.
|
|
185
|
+
Use `specset agent runners revoke <runner-id>` to stop and revoke one remotely, including an offline runner after a crash.
|