@specset/cli 2.0.0 → 2.1.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 +24 -6
- package/dist/main.js +32405 -25394
- package/package.json +2 -2
- package/plugin/specset/.claude-plugin/plugin.json +1 -1
- package/plugin/specset/.codex-plugin/plugin.json +1 -1
- package/plugin/specset/skills/specset/SKILL.md +2 -3
- package/plugin/specset/skills/specset-admin/SKILL.md +12 -7
- package/plugin/specset/skills/specset-agent/SKILL.md +33 -21
- package/plugin/specset/skills/specset-closeout/SKILL.md +6 -10
- package/plugin/specset/skills/specset-projects/SKILL.md +1 -1
- package/plugin/specset/skills/specset-submittals/SKILL.md +7 -0
- package/plugin/specset/skills/specset-tools/SKILL.md +4 -4
- package/skills/specset/SKILL.md +2 -3
- package/skills/specset-admin/SKILL.md +12 -7
- package/skills/specset-agent/SKILL.md +33 -21
- package/skills/specset-closeout/SKILL.md +6 -10
- package/skills/specset-projects/SKILL.md +1 -1
- package/skills/specset-submittals/SKILL.md +7 -0
- package/skills/specset-tools/SKILL.md +4 -4
|
@@ -40,11 +40,9 @@ specset agent show <threadId>
|
|
|
40
40
|
specset agent export <artifactId> --format docx --out ./filled-rfi.docx
|
|
41
41
|
specset agent export <artifactId> --format pdf --out ./filled-rfi.pdf
|
|
42
42
|
|
|
43
|
-
# Pin the host and organization when inspecting a
|
|
44
|
-
specset agent show <threadId-or-link> --host
|
|
43
|
+
# Pin the host and organization when inspecting a run on another deployment
|
|
44
|
+
specset agent show <threadId-or-link> --host <host> --org <slug-or-id> --json
|
|
45
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
|
|
48
46
|
```
|
|
49
47
|
|
|
50
48
|
Use `--json` for machine-readable output (all commands accept it). Long-running questions may need `--timeout <seconds>` — document analysis can take a few minutes.
|
|
@@ -99,7 +97,23 @@ Inspect `getDrawingGraphOverview` bundles and quality flags before a benchmark;
|
|
|
99
97
|
building the graph does not reprocess stale source nodes. `--autoApprovePlan`
|
|
100
98
|
allows immediate execution when the brief is already approved.
|
|
101
99
|
`agent approve --deny --reason "…"` rejects a pending proposal for revision.
|
|
102
|
-
`agent stop <threadId>`
|
|
100
|
+
`agent stop <threadId>` stops a running review and everything under it.
|
|
101
|
+
|
|
102
|
+
A follow-up message to a busy review (`agent chat --thread <threadId>`) does not
|
|
103
|
+
stop the workers it is running: it waits for them and applies at the next step,
|
|
104
|
+
beside their reports. `agent chat` then returns at once with a `held` line
|
|
105
|
+
instead of polling, and `agent show` lists the message under `queued` until the
|
|
106
|
+
review reads it. Stop is what interrupts at once. To steer a busy review, list
|
|
107
|
+
what it is running and stop single workers; the review records a stopped worker
|
|
108
|
+
as stopped and carries on, and can read the stopped worker's thread to see what
|
|
109
|
+
it finished.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
specset agent workers list <threadId> # running workers: id, status, steps, type, title
|
|
113
|
+
specset agent workers list <threadId> --all --json # finished ones too, machine-readable
|
|
114
|
+
specset agent workers stop <workerThreadId> # stop one worker; the review carries on
|
|
115
|
+
specset agent stop <threadId> # stop the review and every worker
|
|
116
|
+
```
|
|
103
117
|
|
|
104
118
|
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
119
|
|
|
@@ -119,22 +133,17 @@ specset agent start --type DrawingReview --project <projectId> \
|
|
|
119
133
|
|
|
120
134
|
- `--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
135
|
- `--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
136
|
- 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.
|
|
137
|
+
- `--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 for a new thread; a message to an existing one (`agent chat --thread`) keeps that thread's approval setting unless `--autoApprove` or `--noAutoApprove` is passed. `--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). For a quick test of a Standard or Deep review, `--reviewMaxWorkers 3` caps the workers it starts (the server refuses more; the root records the rest as not examined). Native tools let a local run's harness use its own tools in the run's workspace and run sandboxed code over document and drawing reads, cropping and enlarging a detail. A thread that starts running locally has them on unless it already chose; `--noNativeTools` (both commands) or the conversation's Settings toggle turns them off.
|
|
126
138
|
- `--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.
|
|
139
|
+
- `agent show <threadId> --wait` waits for a new thread's first turn (`agent start`, `agent serve --message` without `--thread`), or for a run already in progress, to finish or stop for input, then prints it, using the same completion check as `agent chat`. A turn queued on a thread whose last turn finished still reads as done until it starts, so send follow-ups with `agent chat --thread`, which waits for its own turn. `--timeout` sets the wait in seconds (default 600). It exits non-zero when the wait times out or the run ended in an error.
|
|
127
140
|
|
|
128
141
|
## Notes
|
|
129
142
|
|
|
130
143
|
- Keep one thread per topic: follow-ups via `--thread` give the agent the prior context and produce better answers than fresh threads.
|
|
131
|
-
-
|
|
144
|
+
- `agent chat` approves every tool by default, so changes the agent makes (creating submittals, updating records) are applied without a confirmation step. Confirm with the user before asking it to change data, or pass `--noAutoApprove` so its proposals wait for approval in the Specset UI or `agent approve`. To make changes headlessly yourself, use the mutations documented in the domain skills.
|
|
132
145
|
- The agent answers from the project you scope it to; double-check the `--project` id when results look unrelated.
|
|
133
146
|
|
|
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
147
|
## Run agent threads locally with your own Claude Code / Codex
|
|
139
148
|
|
|
140
149
|
`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.
|
|
@@ -151,17 +160,20 @@ Codex uses `CODEX_PATH` when set, then `codex` on PATH, then the managed runtime
|
|
|
151
160
|
**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
161
|
|
|
153
162
|
```bash
|
|
154
|
-
specset agent serve --host <deployment> --org <slug> --
|
|
163
|
+
specset agent serve --host <deployment> --org <slug> & # --account claude2,codex limits it to those accounts
|
|
155
164
|
specset agent show <thread link> # the transcript so far
|
|
165
|
+
specset agent show <thread link> --wait # wait for the run to finish or stop for input
|
|
156
166
|
```
|
|
157
167
|
|
|
158
168
|
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
169
|
|
|
160
170
|
### Native tools and the run workspace
|
|
161
171
|
|
|
162
|
-
Native tools are
|
|
172
|
+
Native tools are on for a thread that starts running locally, unless the thread already chose (an earlier on or off stands): the harness can then run shell commands and read, search or edit files in the run workspace. Turn them off with **Native tools** in the conversation's Settings or `--noNativeTools`; with them off, the harness only calls Specset functions, which the server authorizes and executes (approvals stay in the web app). Each action is mirrored into the conversation as a local action card, and the thread's **Permissions** setting picks the tools: Read only (reads), Accept edits (and edits), Auto or Full access (and the shell; Full asks nothing). In every mode the commands and file tools are sealed in the run's workspace: commands read nothing of the machine but the system and its developer tools (Python, git, Homebrew), write only in the workspace and a private temp directory, reach no network, and never see a credential, so your home, `~/.ssh`, the keychains, every harness's home, `~/.config`, the runner's other directories and the shared temp directories stay closed. Claude Code runs Bash in its command sandbox, which also refuses writes to `.git/config` and `.git/hooks` (git works in an existing repository, but a new one can't be created there), and a hook holds its file tools to the workspace. That hook checks a path before Claude Code opens it, so in Auto and Full a command left running in the background could race it by swapping in a symlink; the commands themselves stay sealed. Codex runs under a permissions profile the runner builds and asks for no approval, so an escalation is declined. The seal needs macOS and, for Codex, a binary the runner checked enforces the profile; elsewhere a step runs with Specset tools only. Native sub-agents stay off; Specset's own sub-agent and fan-out tools run through the same machine. Native tools apply where the harness can run them, so turning them on or off never moves a running thread to another harness. Antigravity uses Specset tools only unless it is on macOS, its `agy --version` is a checked release (1.4.2), and the owner has set `runner.antigravityNativeTools.escapeTestedVersion: "1.4.2"` in `~/.config/specset/config.yml` after the sandbox escape tests pass. A different or unreadable version turns its native tools off again. Its commands use agy's sandbox. Recursive native searches (`grep_search`, `find_by_name`) are disabled; use sandboxed command searches in Auto/Full modes. Its file tools use the same real-path check with the same concurrent-symlink race limitation as Claude Code. It launches from a private read-only project so configuration left in the shared workspace cannot run as agy hooks or MCP servers; writes to `.agents/`, `AGENTS.md` and `GEMINI.md` are also refused by file tools. Clipboard and other macOS services remain reachable from the command sandbox. The Settings menu still labels Antigravity tiers as running without native tools; this opt-in capability is checked by the runner, and helper document reads on Antigravity still run without code.
|
|
173
|
+
|
|
174
|
+
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 and has no network, so the harness cannot download into it: project material comes through Specset tools, and the model writes what it needs from their results into the workspace. On Antigravity, attachments and file results are saved separately in private read-only input storage at the absolute paths supplied to the model; copy them into the workspace before editing. Findings cite the Specset link, never the local path.
|
|
163
175
|
|
|
164
|
-
|
|
176
|
+
With Native tools on and Permissions Auto or Full, the vision tier's document and drawing reads (`examineDrawingSheets`, `examineDocument`, `examineFile` and the like) may also run code to look closer at their attachments: crop a dense detail from the full-resolution file and view it enlarged. Such a read runs in its own scratch directory holding only its attachments (`inputs/attachment-N.png|pdf`), never the run workspace. Its commands are sandboxed: no network, no credentials in their environment, and nothing readable but the system, developer tools, Homebrew (for Python and Pillow) and that directory. Your own temp directory, where other applications keep files, stays closed except, under Claude Code, for the scratch files macOS's `sips` saves there; the shared `/tmp` stays closed. Claude Code's command sandbox denies reading by default, a hook holds its Read tool to the directory, and zsh skips your startup files; Codex runs under a permissions profile that adds only Homebrew and its own binary, with the core environment, so it crops with Pillow and `sips` fails; the runner first checks once that the binary enforces the profile (Codex before 0.157.1 ignores its deny entries), and otherwise runs these reads without code. Code execution needs macOS: on Linux, Claude Code's bubblewrap sandbox leaves the credentials it removes readable to commands through its own process, so these reads run without code there. Its actions are printed in the `agent serve` terminal, because a helper read's actions never reach the conversation. These reads were evaluated on the cloud models without code execution, so treat code-execution results as unevaluated.
|
|
165
177
|
|
|
166
178
|
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
179
|
|
|
@@ -169,17 +181,17 @@ Sessions are ephemeral (`persistSession: false` for Claude, `ephemeral: true` fo
|
|
|
169
181
|
|
|
170
182
|
### Serve multiple local threads
|
|
171
183
|
|
|
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.
|
|
184
|
+
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. It serves from the accounts `specset harness list` shows (config.yml's `runner:` block, or the logins this shell would use when none are listed); `specset harness add claude2 --harness claude --home ~/.claude2 --preferred` adds another login, and `--account` limits one run. 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 each account's runtime before registering. Run a separate `serve --host <deployment>` process for each dev worktree. Each process prints and pins its host/org/accounts at startup; later CLI host/org changes cannot redirect it. Login and selected org 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
185
|
|
|
174
186
|
`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
187
|
|
|
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.
|
|
188
|
+
For an unattended kickoff, `--autoApprovePlan` skips the plan sign-off and `--autoApprove` approves Specset tools for that message (default off for a thread `serve` creates; with `--thread`, omit it to keep the thread's setting). `--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
189
|
|
|
178
|
-
Pin both `--host <deployment>` and `--org <slug>` when using `agent chat`, `agent start`, `agent show`, `agent inspect`, `agent approve` or `agent
|
|
190
|
+
Pin both `--host <deployment>` and `--org <slug>` when using `agent chat`, `agent start`, `agent show`, `agent inspect`, `agent approve`, `agent stop` or `agent workers`; these overrides do not change the CLI’s saved selection.
|
|
179
191
|
|
|
180
|
-
The
|
|
192
|
+
Every model call carries its routing tier (conversation, orchestrator, planner, analyst, worker, lite, balanced, query, vision), and each tier names a model that any account whose harness offers it serves. The defaults match the app; `specset harness list` prints each tier's current model and the class it runs as. Antigravity is opt-in: it serves those tiers only after you add an account for it (`specset harness add agy --harness antigravity`); until then they run their model's class on Claude Code or Codex, or in the cloud with `harness fallback`. A model no account offers runs as its class (frontier, standard, fast) on a harness the machine has. Change a tier with `specset harness tier <tier> <model[:effort]>`, a class's model with `specset harness model <harness> <class> <model> [--effort e]`, or one run's with `agent serve --tier conversation=opus`. The conversation's Settings pins a class or one of the reported models per harness for that thread's own steps, plus a reasoning effort; children and helper calls keep the tiers. When the preferred accounts for a model are at their limits, `specset harness failover sameModel|any|off` decides where its calls go (default sameModel: other accounts with the same model; any: also the same class elsewhere); a call that already streamed fails instead and the next one goes elsewhere. A provider rate limit (HTTP 429) is waited out rather than failing the run: the server retries the call once the account's short wait passes (on another account if one has room), unless it already ran a native command or edit, which a retry could repeat; only every account being at its usage limit stops the run. A call whose input a harness refuses for its size (Codex caps a turn's input at 1,048,576 characters) is never retried there: it moves to another harness the failover setting allows, else to its tier's cloud model when the tier falls back to the cloud, else fails naming the cause. `specset harness fallback <tier|all> cloud` (or `agent serve --fallback analyst=cloud`) sends a tier's calls to Specset's cloud model, billed to the organization, instead of another provider's whenever no account here can serve its model (none offers it, or its accounts are at their limits); `local` is the default. `--concurrency` defaults to 5 (at most 16) 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. `specset harness limits --concurrency 16 --maxThreads 300 --maxRunSeconds 43200` saves them in config.yml for every `agent serve` (a flag still wins for one run; `default` clears one; no flags prints them). 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
193
|
|
|
182
|
-
Harness tool callbacks can only wait for results supplied by the server. Each job receives private harness configuration and a minimal environment
|
|
194
|
+
Harness tool callbacks can only wait for results supplied by the server. Each job receives private harness configuration and a minimal environment, and no CLI login: a native session's commands reach no network, so project material comes through Specset tools. 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. The harness itself still runs as the local OS user, outside the seal its commands run in. Use a dedicated account or isolated host for untrusted project content; do not share this personal runner across users.
|
|
183
195
|
|
|
184
196
|
Use `specset agent runners list --json` to inspect your registrations.
|
|
185
197
|
Use `specset agent runners revoke <runner-id>` to stop and revoke one remotely, including an offline runner after a crash.
|
|
@@ -12,14 +12,14 @@ Run every operation with `specset api`. All ids are plain UUIDs. Inline enums, n
|
|
|
12
12
|
|
|
13
13
|
**Locations** are the spatial scaffold (site → building → level → room), nesting through `parentId`. **Systems** are disciplines and equipment groups, also nested. **Products** are specified make/models. **Assets** are installed instances: each asset has a location, may reference a product and responsible company, and can join multiple systems. **Warranties** attach to assets.
|
|
14
14
|
|
|
15
|
+
**Companies** belong to the organization's directory and are shared by its projects. A company works on a project through a **ProjectCompany** row, which holds that project's `role`, `notes`, `archived` state and closeout documentation. Assigning a directory company to a project record (an asset's responsible company, a part's vendor, a submittal's or RFI's responsible contractor) adds it to the project.
|
|
16
|
+
|
|
15
17
|
Maintenance has three layers:
|
|
16
18
|
|
|
17
19
|
- **Procedure** — reusable checklist content: ordered typed fields, descriptions, and source references.
|
|
18
20
|
- **MaintenancePlan** — a schedule on exactly one Product, Asset, Location, or System. Product plans fan out to installed assets. Its `tiers` are independent schedule items that pair a Procedure with a calendar cadence, meter trigger, or both.
|
|
19
21
|
- **WorkOrder** — a concrete occurrence or ad-hoc job. Generated work orders snapshot their checklist fields, so history remains stable when a Procedure changes.
|
|
20
22
|
|
|
21
|
-
`MaintenanceTask` and its completion API no longer exist. Use Procedure, MaintenancePlan, and WorkOrder operations below.
|
|
22
|
-
|
|
23
23
|
## Discover Before Mutating
|
|
24
24
|
|
|
25
25
|
Input objects evolve, especially checklist fields and plan tiers. Introspect the relevant input before composing a mutation:
|
|
@@ -55,6 +55,7 @@ Notable differences:
|
|
|
55
55
|
|
|
56
56
|
- Asset creation requires `projectId` and `locationId`. `paginatedAssets` accepts `search` and filters such as `statuses`, `locationIds`, `productIds`, `systemIds`, `responsibleCompanyIds`, `parentIds`, and `archived`.
|
|
57
57
|
- Warranty is asset-scoped; use `warrantiesByAsset(assetId)` to browse one asset's warranties.
|
|
58
|
+
- Company is org-wide: `paginatedCompanies(orgId: ...)` lists the directory and `searchCompanies(orgId, search)` finds a company by name. `paginatedProjectCompanies(projectId)` lists a project's companies with their `role`; `addCompaniesToProject(projectId, companyIds)`, `removeCompaniesFromProject(projectId, companyIds)` (refused while a project record still names the company) and `updateProjectCompany(input: { id, role, notes, archived })` manage the participation. `createCompany(input: { projectId, ... })` creates the directory company and puts it on that project.
|
|
58
59
|
- Location, Product, Company, System, and Asset updates support reversible `archived` state. Prefer archiving to deletion.
|
|
59
60
|
- Batch-delete availability varies. Introspect the mutation root rather than guessing an operation name.
|
|
60
61
|
|
|
@@ -177,7 +178,7 @@ specset api --query 'mutation { setProductDocumentRoles(productId: "<product-id>
|
|
|
177
178
|
|
|
178
179
|
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
|
|
|
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
|
+
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. A company's block is per project: use `updateProjectCompanyDocumentation` / `markProjectCompanyDocumentationComplete` with the ProjectCompany id. 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
|
|
|
182
183
|
### Writing documentation that reads well in the O&M package export
|
|
183
184
|
|
|
@@ -315,12 +316,7 @@ specset files download <file-resource-id> --out manual.pdf # once workflow.s
|
|
|
315
316
|
|
|
316
317
|
## Enabling closeout
|
|
317
318
|
|
|
318
|
-
`CloseoutAuthService.isCloseoutActive` requires the org SKU **and** (unless the org is in `fmMode`) the project toggle.
|
|
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
|
-
```
|
|
319
|
+
`CloseoutAuthService.isCloseoutActive` requires the org's closeout SKU **and** (unless the org is in `fmMode`) the project's closeout toggle. Specset staff turn both on; when closeout operations report closeout as inactive, ask your Specset contact to enable it.
|
|
324
320
|
|
|
325
321
|
## Dedup / Re-pointing
|
|
326
322
|
|
|
@@ -331,7 +327,7 @@ For duplicate products P1 (loser) and P2 (survivor):
|
|
|
331
327
|
3. Re-run the filtered query and confirm zero remaining references.
|
|
332
328
|
4. Archive P1 with `updateProduct(input: { id: P1, archived: true })`.
|
|
333
329
|
|
|
334
|
-
Use the same impact-first pattern for duplicate companies,
|
|
330
|
+
Use the same impact-first pattern for duplicate locations and systems. Duplicate companies merge in one step: `mergeCompanies(targetId, sourceIds)` moves their projects, documents, record assignments, people and Procore links to the target, fills the target's blank profile fields from theirs (in `sourceIds` order), and archives the duplicates; it is not reversible, so confirm the pair first. `companyDuplicates(orgId)` lists likely pairs (names that differ only in case, punctuation or a legal form), and `companies(ids)` loads them side by side.
|
|
335
331
|
|
|
336
332
|
## Safety
|
|
337
333
|
|
|
@@ -26,7 +26,7 @@ project(id: ID!): Project!
|
|
|
26
26
|
|
|
27
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.
|
|
28
28
|
|
|
29
|
-
1. Create it with the project command
|
|
29
|
+
1. Create it with the project command (new projects support drawing graphs automatically):
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
specset projects create 'Riverside Medical Center' --json
|
|
@@ -14,6 +14,13 @@ How the data is shaped:
|
|
|
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).
|
|
16
16
|
|
|
17
|
+
Two common flows have purpose-built commands; prefer them to hand-written mutations:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
specset submittals create --project <projectId> --file ./package.pdf --json # uploads the file and creates the submittal from it; --title, repeatable --specSection <id>
|
|
21
|
+
specset submittals review --submittal <submittalId|link> --wait --json # runs a compliance review and prints its issues; exits non-zero when it times out or the review fails; repeatable --specSection, --prompt, --timeout (default 3600)
|
|
22
|
+
```
|
|
23
|
+
|
|
17
24
|
## Reading
|
|
18
25
|
|
|
19
26
|
```bash
|
|
@@ -65,15 +65,15 @@ The retrieval tools return **extracted text**, which is authoritative for schedu
|
|
|
65
65
|
| Entity | Command | Also accepts | Formats / options |
|
|
66
66
|
| -------------- | ----------------------------------------------------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
67
67
|
| Drawing sheets | `specset drawings download 'https://app.specbook.ai/go/drawing/<uuid>'` | sheet number + `--project` | `--format image` (rendered PNG, default), `pdf` (single sheet), `file` (whole set) |
|
|
68
|
-
| Documents | `specset docs download 'https://app.specbook.ai/go/doc/<uuid>'` | | also covers RFI attachments and closeout documents
|
|
68
|
+
| Documents | `specset docs download 'https://app.specbook.ai/go/doc/<uuid>'` | | `--original` (uploaded file, not the converted PDF); also covers RFI attachments and closeout documents |
|
|
69
69
|
| Spec sections | `specset specs download 'https://app.specbook.ai/go/spec/<uuid>'` | section number (e.g. `'23 31 19'`) + `--project` | per-section PDF slice (default), `--asset book` (whole source spec file) |
|
|
70
70
|
| Submittals | `specset submittals download 'https://app.specbook.ai/go/sub/<uuid>'` | | compiled package (default when present); `--list` shows the asset inventory; `--asset attachment --index 2`, `--asset attachment --all` |
|
|
71
71
|
| RFIs | `specset rfis download 'https://app.specbook.ai/go/rfi/<uuid>'` | | question + response attachments; `--list`, `--all` |
|
|
72
|
-
| File resources | `specset files download 'https://app.specbook.ai/go/file/<uuid>'` | | escape hatch for a returned file source link
|
|
72
|
+
| File resources | `specset files download 'https://app.specbook.ai/go/file/<uuid>'` | | escape hatch for a returned file source link; `--original` (uploaded file, not the converted PDF) |
|
|
73
73
|
|
|
74
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.
|
|
75
75
|
|
|
76
|
-
`drawings download` also
|
|
76
|
+
`docs download`, `drawings download`, `files download` and `specs download` also accept `--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 <slug> --host <host> --format pdf` or `specset specs download '08 71 00' --project <id> --org <slug> --host <host> --out hardware.pdf`.
|
|
77
77
|
|
|
78
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
79
|
|
|
@@ -99,7 +99,7 @@ Graph tools are automatically available with `--project` for eligible projects (
|
|
|
99
99
|
specset drawings build-graph --project <id> --wait --timeout 1800 --host <host> --json
|
|
100
100
|
```
|
|
101
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.
|
|
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.
|
|
103
103
|
|
|
104
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
105
|
|