@figs-so/cli 0.1.8 → 0.1.10

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.
Files changed (2) hide show
  1. package/figs.mjs +31 -4
  2. package/package.json +1 -1
package/figs.mjs CHANGED
@@ -27,6 +27,7 @@
27
27
  */
28
28
 
29
29
  import {
30
+ chmodSync,
30
31
  existsSync,
31
32
  mkdirSync,
32
33
  readFileSync,
@@ -37,7 +38,7 @@ import { homedir } from "node:os"
37
38
  import { join } from "node:path"
38
39
  import { randomUUID } from "node:crypto"
39
40
 
40
- const VERSION = "0.1.8"
41
+ const VERSION = "0.1.10"
41
42
  // Going-forward default; override with FIGS_ENDPOINT or .figs/config.json endpoint
42
43
  // (e.g. FIGS_ENDPOINT=http://localhost:3000 for local dev).
43
44
  const DEFAULT_ENDPOINT = "https://app.figs.so"
@@ -292,8 +293,17 @@ function sleep(ms) {
292
293
  return new Promise((r) => setTimeout(r, ms))
293
294
  }
294
295
  function saveToken(token) {
295
- mkdirSync(globalDir, { recursive: true })
296
- writeFileSync(globalCreds, JSON.stringify({ token }, null, 2) + "\n")
296
+ // A bearer token must not be group/other-readable: dir 0700, file 0600.
297
+ mkdirSync(globalDir, { recursive: true, mode: 0o700 })
298
+ writeFileSync(globalCreds, JSON.stringify({ token }, null, 2) + "\n", { mode: 0o600 })
299
+ // Enforce perms even if the dir/file pre-existed with looser modes (mode on
300
+ // write only applies at creation).
301
+ try {
302
+ chmodSync(globalDir, 0o700)
303
+ chmodSync(globalCreds, 0o600)
304
+ } catch {
305
+ /* best-effort — non-POSIX filesystems */
306
+ }
297
307
  }
298
308
 
299
309
  /**
@@ -374,12 +384,16 @@ async function status() {
374
384
 
375
385
  let loggedIn = false
376
386
  let list = null
387
+ let account = null
377
388
  let unreachable = false
378
389
  if (token) {
379
390
  const r = await request("GET", "/api/workspaces", null, token)
380
391
  loggedIn = r.ok
381
392
  unreachable = r.status === 0
382
- if (r.ok) list = r.data.workspaces ?? []
393
+ if (r.ok) {
394
+ list = r.data.workspaces ?? []
395
+ account = r.data.user ?? null // null on a pre-account server
396
+ }
383
397
  }
384
398
 
385
399
  if (JSON_OUT) {
@@ -389,6 +403,9 @@ async function status() {
389
403
  version: VERSION,
390
404
  endpoint,
391
405
  loggedIn,
406
+ account: account
407
+ ? { id: account.id, email: account.email, name: account.name }
408
+ : null,
392
409
  workspaces: list?.map((w) => ({ id: w.id, name: w.name, role: w.role })),
393
410
  config: cfg ? { workspaceId: cfg.workspaceId, agentId: cfg.agentId } : null,
394
411
  agentJson: hasAgent,
@@ -413,6 +430,14 @@ async function status() {
413
430
  ? "token invalid — run `figs login`"
414
431
  : "no — run `figs login`",
415
432
  )
433
+ if (loggedIn) {
434
+ row(
435
+ "account",
436
+ account?.email
437
+ ? `${account.email}${account.name ? ` (${account.name})` : ""}`
438
+ : "—",
439
+ )
440
+ }
416
441
  row(
417
442
  "workspace",
418
443
  cfg?.workspaceId
@@ -611,6 +636,8 @@ async function push() {
611
636
  console.log(
612
637
  `figs: ✓ pushed ${agent.name ?? agent.id} — ${runs.length} runs, ${asks.length} asks`,
613
638
  )
639
+ // The wow-moment link — relay this to your human so they can see the agent.
640
+ console.log(` view at ${base}/w/${config.workspaceId}`)
614
641
 
615
642
  await pushArtifacts(base, token, config, runs, asks)
616
643
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@figs-so/cli",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
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": {