@clipboard-health/groundcrew 4.50.3 → 4.50.4

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 CHANGED
@@ -112,7 +112,7 @@ crew task get <TASK> [--source <name>] [--prompt] # inspect one task or i
112
112
  crew task create "Title" --source <name> [--agent <name>] # create a source task
113
113
  crew task done <TASK> [--allow-dirty] # mark a no-PR task done
114
114
  crew task validate [<source>] # validate task content
115
- crew status [<TASK>] # inspect current state or one task
115
+ crew status [<TASK>] [--json [--local-only]] # inspect current state, or emit it as JSON
116
116
  crew run [--watch] # one-shot or --watch forever
117
117
  crew start <TASK> # provision + launch one task now
118
118
  crew stop <TASK> [--reason <text>] # stop workspace, keep worktree
@@ -127,6 +127,50 @@ crew completions <bash|zsh|fish> # print a shell completi
127
127
 
128
128
  See [command details](./docs/commands.md) for status output, doctor behavior, and the stop/resume workflow.
129
129
 
130
+ ### Status snapshots for external monitors
131
+
132
+ `crew status --json` prints two documents and writes them beside the log file:
133
+
134
+ ```text
135
+ <state-dir>/status-local.json # worktrees, run states, sessions, git status
136
+ <state-dir>/status-remote.json # board, pull requests
137
+ ```
138
+
139
+ The two are split by cost. The local tier is local subprocess work, so it is
140
+ safe to poll every few seconds. The remote tier is network-bound and
141
+ rate-limited, so poll it near your `pollIntervalMilliseconds`.
142
+
143
+ ```bash
144
+ crew status --json # both tiers
145
+ crew status --json --local-only # local tier only; never touches the network
146
+ ```
147
+
148
+ `--local-only` is a guarantee about that invocation, not a computed outcome, so
149
+ a monitor's fast loop cannot stall on a slow board or a `gh` timeout.
150
+
151
+ Three rules a reader must honor:
152
+
153
+ - **Subtract locally.** `status-remote.json` ships board classification without
154
+ the local worktree subtraction. Remove tasks present in the local document
155
+ from `inProgress`, `queueReady`, and `queueBlocked` yourself. Precomputing
156
+ that join would report a just-dispatched task as still queued until the next
157
+ slow poll, which is a false statement rather than stale data.
158
+ - **Join pull requests on the worktree directory.** `pullRequestsByWorktree` is
159
+ keyed by absolute worktree path, not by task, because a task with two
160
+ worktrees has two branches. An empty or missing entry means no pull requests
161
+ were found, or the `gh` lookup for that worktree failed; the two are not
162
+ distinguishable.
163
+ - **Read the right timestamp.** `payload.capturedAt` describes the last
164
+ successful fetch; `lastAttemptAt` describes the most recent try. Read
165
+ `lastAttemptStatus` to answer "is the board healthy", and `capturedAt` to
166
+ answer "how old is this queue". A failed fetch keeps the previous payload, so
167
+ last-known-good data survives an outage while the document still says the
168
+ board is unreachable.
169
+
170
+ Durations are never stored, only start instants, so a reader must derive
171
+ elapsed time itself. A cached duration would show a frozen clock, which reads
172
+ as "the agent stopped working" when it did not.
173
+
130
174
  ## Configuration
131
175
 
132
176
  Workspace settings and at least one enabled agent are required; everything else has a default.
package/dist/cli.js CHANGED
@@ -144,7 +144,7 @@ const SUBCOMMANDS = {
144
144
  },
145
145
  status: {
146
146
  summary: "Print read-only groundcrew state, or one task's local/Linear status",
147
- usage: "[<task>]",
147
+ usage: "[<task>] [--json [--local-only]]",
148
148
  invoke: statusCli,
149
149
  },
150
150
  cleanup: {
@@ -1,6 +1,22 @@
1
+ /**
2
+ * Renderers for `crew status`. Three output modes share this file.
3
+ *
4
+ * With no task it renders the inventory: it calls the collectors in
5
+ * statusCollect.ts, joins the two tiers with joinStatus, and prints text.
6
+ * With a task it renders that one task, doing its own I/O rather than using
7
+ * the collectors, because it reads the whole log where they read a tail.
8
+ * With --json it prints and persists the wire documents from statusSnapshot.ts.
9
+ * Text mode persists nothing.
10
+ *
11
+ * @see README.md#status-snapshots-for-external-monitors for the reader contract.
12
+ */
1
13
  import { type ResolvedConfig } from "../lib/config.ts";
2
14
  export interface StatusOptions {
3
15
  task?: string;
16
+ /** Emit the snapshot documents as JSON and persist them. */
17
+ json?: boolean;
18
+ /** Collect the local tier only. Guarantees this run makes no network call. */
19
+ localOnly?: boolean;
4
20
  }
5
21
  export declare function status(config: ResolvedConfig, options?: StatusOptions): Promise<void>;
6
22
  export declare function statusCli(argv: string[]): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAenE,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAosBD,wBAAsB,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/F;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AA0CnE,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA0hBD,wBAAsB,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAe/F;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7D"}