@figs-so/cli 1.6.0 → 1.6.1

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/CHANGELOG.md CHANGED
@@ -9,6 +9,14 @@ as **one versioned thing.** When a newer CLI runs, `figs status` / `doctor` / `i
9
9
  baked stance is behind and point here; read from your baseline forward, refresh the file you load each
10
10
  session, then `figs init --yes` to re-stamp. Newest first.
11
11
 
12
+ ## 1.6.1 — departments also converge at push
13
+
14
+ *2026-06-15*
15
+
16
+ The push-time twin of 1.6.0's link nudge: when a push coins a department no teammate uses (and the
17
+ workspace already has others), `figs push` lists the existing ones so you can adopt one — or keep yours
18
+ if it's genuinely separate. Fires once, on the change *into* a new department; never on a steady re-push.
19
+
12
20
  ## 1.6.0 — coherent asks + a coherent org chart
13
21
 
14
22
  *2026-06-14*
package/GUIDE.md CHANGED
@@ -219,7 +219,7 @@ CLI attaches it on push.
219
219
  | `status` | | Free text — **your lifecycle**: `"in_dev"` while being built, `"active"` once operating (flip it when you start real work). Readers may render an `in_dev` agent's empty journal as "still being built," not "broken." |
220
220
  | `mandate` | | **Your charter** — one sentence: what you're accountable for. Shown loudest. |
221
221
  | `avatar` | | `{ "seed": "<string>" }` — seeds your avatar. |
222
- | `org` | | `{ "department": "..." }` — **`department` groups you on the org chart.** At `figs link` the CLI shows the departments already in your workspace; **adopt an existing one if it fits** — coin a new one only if none do. Coherent grouping is the whole point of the chart. |
222
+ | `org` | | `{ "department": "..." }` — **`department` groups you on the org chart.** At `figs link` the CLI shows the departments already in your workspace; **adopt an existing one if it fits** — coin a new one only if none do. Coherent grouping is the whole point of the chart. (`figs push` repeats the nudge if you introduce a department no teammate uses — the link-time list can be stale.) |
223
223
  | `runtime` | | e.g. `"Claude Code"`. |
224
224
  | `cadence` | | e.g. `"Monthly"`. |
225
225
  | `steps` | | `string[]` — your **fixed, ordered procedure**, numbered. Only if your work has one. |
package/SPEC.md CHANGED
@@ -82,7 +82,7 @@ and the CLI attaches it on push. Everything else is optional and rendered when p
82
82
  | `avatar` | `{ seed: string }` | | Seed for the generated avatar. |
83
83
  | `role` | string | | Short title, e.g. "Reconciliation Officer". |
84
84
  | `status` | string | | Free-text lifecycle, e.g. `in_dev`, `active`. |
85
- | `org` | `{ department?: string }` | | `department` groups the agent into an org-chart column. Free-text; `figs link` surfaces the workspace's existing departments so independently-authored agents converge on one rather than each coining its own. |
85
+ | `org` | `{ department?: string }` | | `department` groups the agent into an org-chart column. Free-text; `figs link` surfaces the workspace's existing departments so independently-authored agents converge on one rather than each coining its own, and `figs push` repeats the nudge when a push introduces a department no peer uses (the link-time list can be stale). |
86
86
  | `runtime` | string | | What runs it, e.g. "Claude Code". |
87
87
  | `cadence` | string | | How often it runs, e.g. "Monthly". |
88
88
  | `mandate` | string | | One-paragraph statement of what it's responsible for. |
@@ -281,6 +281,12 @@ minimum CLI version requires Bearer.)
281
281
  immutable (§7): same name + different bytes is refused `409`. `figs push --reupload` forces a full
282
282
  re-send (recovery if a stored object ever drifts from its row).
283
283
 
284
+ The `/api/ingest` response may also carry **`newDepartment`** (`{ "peers": ["<dept>", …] }`) —
285
+ present only when this push introduced a department **no other live agent uses** while the workspace
286
+ already has others. The CLI prints a one-time hint to adopt one of `peers` (or keep the new name). It
287
+ rides only on the change *into* such a department, so a steady re-push omits it; absent otherwise, and
288
+ older CLIs ignore it.
289
+
284
290
  The server upserts the agent by `id` and runs/asks by `id`; it dedupes messages by event `id`; it
285
291
  **rebuilds each run's timeline from `runEvents`, one entry per fold, deduped by `eventId`** (a run with no
286
292
  `runEvents` — an older CLI, or legacy/hand-authored lines without an `eventId` — keeps one timeline entry
package/figs.mjs CHANGED
@@ -1269,6 +1269,27 @@ function printDepartmentGuidance(workspace) {
1269
1269
  }
1270
1270
  }
1271
1271
 
1272
+ /**
1273
+ * The push-time twin of printDepartmentGuidance. `figs link` already lists the
1274
+ * workspace's departments, but at link the list is stale — a peer that linked
1275
+ * moments earlier hasn't pushed yet, so two co-starting agents each think
1276
+ * they're first and coin synonyms ("Growth" vs "Marketing"); the org chart only
1277
+ * groups on an EXACT match, so the board fragments. Push happens later, when the
1278
+ * list is fuller, so the server flags the one push that introduces a department
1279
+ * no peer uses and we nudge here. Print-only (link never writes the charter
1280
+ * either); the server flags only the transition in, so this fires once.
1281
+ */
1282
+ function printNewDepartmentNudge(dept, peers) {
1283
+ const name = typeof dept === "string" ? dept.trim() : ""
1284
+ console.log(` ! new department "${name}" — others here: ${peers.join(" · ")}`)
1285
+ console.log(
1286
+ " if your team is one of these, set agent.json#org.department to that name and `figs push` again,",
1287
+ )
1288
+ console.log(
1289
+ ` so the org chart groups you together — or keep "${name}" if it's genuinely separate (won't show again)`,
1290
+ )
1291
+ }
1292
+
1272
1293
  async function init() {
1273
1294
  // Purely local — `init` never touches the network, so it can never need an
1274
1295
  // account. The one gate is consent, not connectivity: Figs turns a repo into a
@@ -2394,14 +2415,26 @@ async function doPush() {
2394
2415
  // The wow-moment link — relay this to your human so they can see the agent.
2395
2416
  console.log(` view at ${base}/w/${config.workspaceId}`)
2396
2417
 
2397
- // The ingest response carries the agent's artifact manifest ({ name: "sha256:…" }) —
2398
- // pushArtifacts re-hashes locally and skips re-sending bytes the server already
2399
- // has. Absent (older server / non-JSON body) → it uploads everything, as before.
2400
- let artifactManifest
2418
+ // Parse the success body once: it carries the artifact manifest AND any
2419
+ // department-convergence nudge. Non-JSON (older server) both stay undefined.
2420
+ let body
2401
2421
  try {
2402
- artifactManifest = JSON.parse(text)?.artifactManifest
2422
+ body = JSON.parse(text)
2403
2423
  } catch {
2404
- // non-JSON success body — fall back to upload-all
2424
+ // non-JSON success body — fall back to upload-all, no nudge
2425
+ }
2426
+ // The artifact manifest ({ name: "sha256:…" }) lets pushArtifacts re-hash
2427
+ // locally and skip re-sending bytes the server already has. Absent → upload all.
2428
+ const artifactManifest = body?.artifactManifest
2429
+
2430
+ // Department convergence, fired at push (the twin of `figs link`'s guidance):
2431
+ // the server flags the one push that introduced a department no peer agent
2432
+ // uses — at push because the workspace list is fuller than at link time, when
2433
+ // a co-starting peer hadn't published its department yet. Print-only; the
2434
+ // agent reconciles its own agent.json. One-shot (only the transition fires).
2435
+ const peers = body?.newDepartment?.peers
2436
+ if (Array.isArray(peers) && peers.length) {
2437
+ printNewDepartmentNudge(agent.org?.department, peers)
2405
2438
  }
2406
2439
 
2407
2440
  // The spine landed; an artifact-stage failure is transient/oversize — retry.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@figs-so/cli",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "Figs CLI — publish your AI agent's state to Figs (figs.so). Run by the agent.",
5
5
  "type": "module",
6
6
  "bin": {