@hivefloor/cli 0.1.2 → 0.1.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.
@@ -3,7 +3,7 @@ import {
3
3
  formatRemote,
4
4
  normalizeRemote,
5
5
  runCmd
6
- } from "./chunk-TH4ANHSG.js";
6
+ } from "./chunk-ZC2DAKB5.js";
7
7
 
8
8
  // src/git.ts
9
9
  function remoteOf(url) {
@@ -8,11 +8,11 @@ import {
8
8
  import {
9
9
  defaultHost,
10
10
  loadToken
11
- } from "./chunk-DQV6FAJU.js";
11
+ } from "./chunk-PDXYOREI.js";
12
12
  import {
13
13
  hostFromEnv,
14
14
  normalizeHost
15
- } from "./chunk-TH4ANHSG.js";
15
+ } from "./chunk-ZC2DAKB5.js";
16
16
 
17
17
  // src/session.ts
18
18
  async function resolveSession(ctx, p) {
@@ -3,7 +3,7 @@
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@hivefloor/cli",
6
- version: "0.1.2",
6
+ version: "0.1.4",
7
7
  description: "Connect your coding agents (Claude Code, Codex, Cursor, Gemini, Grok) to Hivefloor: live presence, task coordination and usage on one floor.",
8
8
  author: {
9
9
  name: "Errr0rr404",
@@ -10,12 +10,12 @@ import {
10
10
  removeHooks,
11
11
  restoreFeatureHooks,
12
12
  wasCreated
13
- } from "./chunk-NLZXB26Y.js";
13
+ } from "./chunk-QHYZBHXO.js";
14
14
  import {
15
15
  claudeConfigDirs,
16
16
  codexConfigDir,
17
17
  profileKeys
18
- } from "./chunk-E4V47VEV.js";
18
+ } from "./chunk-UJ4BQFWV.js";
19
19
  import {
20
20
  atomicWrite,
21
21
  backupOnce,
@@ -12,7 +12,7 @@ import {
12
12
  import {
13
13
  cliNpxCommand,
14
14
  runCmd
15
- } from "./chunk-TH4ANHSG.js";
15
+ } from "./chunk-ZC2DAKB5.js";
16
16
 
17
17
  // src/service/units.ts
18
18
  import os from "os";
@@ -17,7 +17,7 @@ import {
17
17
  import {
18
18
  cliNpxCommand,
19
19
  runCmd
20
- } from "./chunk-TH4ANHSG.js";
20
+ } from "./chunk-ZC2DAKB5.js";
21
21
 
22
22
  // src/manifest.ts
23
23
  function readManifest() {
@@ -8,7 +8,7 @@ import {
8
8
  deviceCodeResponseSchema,
9
9
  deviceTokenErrorSchema,
10
10
  deviceTokenSuccessSchema
11
- } from "./chunk-TH4ANHSG.js";
11
+ } from "./chunk-ZC2DAKB5.js";
12
12
 
13
13
  // src/device.ts
14
14
  var printable = (s) => [...s].filter((c) => c.charCodeAt(0) >= 32 && c.charCodeAt(0) !== 127).join("");
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  deviceLogin
4
- } from "./chunk-HT5KXWXM.js";
4
+ } from "./chunk-R5KDI4WI.js";
5
5
  import {
6
6
  RC_LINE,
7
7
  addRcLine,
@@ -13,10 +13,10 @@ import {
13
13
  installGrok,
14
14
  rcFileFor,
15
15
  updateManifest
16
- } from "./chunk-NLZXB26Y.js";
16
+ } from "./chunk-QHYZBHXO.js";
17
17
  import {
18
18
  detectRepo
19
- } from "./chunk-YRNMECUF.js";
19
+ } from "./chunk-2BSA7LFD.js";
20
20
  import {
21
21
  REAL_TOOLS,
22
22
  TOOL_LABEL,
@@ -31,10 +31,10 @@ import {
31
31
  } from "./chunk-TKMIV7BG.js";
32
32
  import {
33
33
  saveToken
34
- } from "./chunk-DQV6FAJU.js";
34
+ } from "./chunk-PDXYOREI.js";
35
35
  import {
36
36
  VERSION
37
- } from "./chunk-LF2NWQ4B.js";
37
+ } from "./chunk-DNG5CRT3.js";
38
38
  import {
39
39
  readMachine
40
40
  } from "./chunk-T7TG6WA4.js";
@@ -51,7 +51,7 @@ import {
51
51
  hostFromEnv,
52
52
  machineName,
53
53
  normalizeHost
54
- } from "./chunk-TH4ANHSG.js";
54
+ } from "./chunk-ZC2DAKB5.js";
55
55
 
56
56
  // src/connect.ts
57
57
  var INSTALLERS = {
@@ -172,7 +172,7 @@ async function connect(ctx, p) {
172
172
  return 2;
173
173
  }
174
174
  if (p.flags.agent || p.flags.tool !== void 0) return connectAgent(ctx, p);
175
- return (await import("./machine-connect-NOQ3VZOO.js")).connectMachine(ctx, p);
175
+ return (await import("./machine-connect-BYHZRRRB.js")).connectMachine(ctx, p);
176
176
  }
177
177
 
178
178
  export {
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VNCQFFQO.js";
8
8
  import {
9
9
  PROFILE_KEY_RE
10
- } from "./chunk-TH4ANHSG.js";
10
+ } from "./chunk-ZC2DAKB5.js";
11
11
 
12
12
  // src/profiles.ts
13
13
  import fs from "fs";
@@ -5,7 +5,7 @@ import {
5
5
  codexConfigDir,
6
6
  codexLabel,
7
7
  profileKeys
8
- } from "./chunk-E4V47VEV.js";
8
+ } from "./chunk-UJ4BQFWV.js";
9
9
 
10
10
  // src/osinfo.ts
11
11
  import os from "os";
@@ -19945,7 +19945,11 @@ var discoveryProfileSchema = external_exports.object({
19945
19945
  running: external_exports.number().int().min(0).max(500)
19946
19946
  }).strict();
19947
19947
  var discoveryBody = external_exports.object({ profiles: external_exports.array(discoveryProfileSchema).max(MACHINE_MAX_AGENTS) }).strict();
19948
- var machineHookEventSchema = hookEventSchema.extend({ profile: profileKeySchema.optional() });
19948
+ var SESSION_ACCOUNT_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,59}$/;
19949
+ var machineHookEventSchema = hookEventSchema.extend({
19950
+ profile: profileKeySchema.optional(),
19951
+ account: external_exports.string().regex(SESSION_ACCOUNT_RE).optional().catch(void 0)
19952
+ });
19949
19953
  var machineHookBatchSchema = external_exports.object({ events: external_exports.array(machineHookEventSchema).min(1).max(HOOK_BATCH_MAX) });
19950
19954
  var approveMachineBody = external_exports.object({
19951
19955
  name: external_exports.string().trim().min(1).max(100),
@@ -20369,7 +20373,11 @@ var usageAccountViewSchema = external_exports.object({
20369
20373
  /** Names of the machines that report this account. */
20370
20374
  machines: external_exports.array(external_exports.string().max(80)).max(50),
20371
20375
  windows: external_exports.array(usageWindowViewSchema).max(20),
20372
- issues: external_exports.array(usageIssueSchema).max(10).optional()
20376
+ issues: external_exports.array(usageIssueSchema).max(10).optional(),
20377
+ /** How many live sessions draw on this account (subagents included). */
20378
+ live_sessions: external_exports.number().int().nonnegative().optional(),
20379
+ /** The live agents that draw on it, most recent first; `working` when one of its sessions works now. */
20380
+ agents: external_exports.array(external_exports.object({ name: external_exports.string().min(1).max(100), machine: external_exports.string().max(80).optional(), working: external_exports.boolean() }).strict()).max(20).optional()
20373
20381
  }).strict();
20374
20382
  var usageMachineViewSchema = external_exports.object({
20375
20383
  id: external_exports.string().min(1).max(80),
@@ -20847,6 +20855,11 @@ var deviceApprovedResponse = external_exports.object({
20847
20855
  repo_link: external_exports.enum(["active", "pending"]).nullable()
20848
20856
  });
20849
20857
 
20858
+ // ../shared/src/floor-range.ts
20859
+ var HOUR_MS = 36e5;
20860
+ var MAX_FLOOR_RANGE_MS = 8 * 24 * HOUR_MS;
20861
+ var DEFAULT_FLOOR_WINDOW_MS = 24 * HOUR_MS;
20862
+
20850
20863
  // ../shared/src/collisions.ts
20851
20864
  var COLLISION_WINDOW_SEC = 30 * 60;
20852
20865
  var LOOP_NO_CHANGE_SEC = 30 * 60;
@@ -21403,6 +21416,7 @@ export {
21403
21416
  MACHINE_MIN_INTERVAL_SECONDS,
21404
21417
  PROFILE_KEY_RE,
21405
21418
  machineHeartbeatResponseSchema,
21419
+ SESSION_ACCOUNT_RE,
21406
21420
  machineTokenSuccessSchema,
21407
21421
  CLI_BIN_NAME,
21408
21422
  CLI_INSTALL_COMMAND,
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-TKMIV7BG.js";
5
5
  import {
6
6
  VERSION
7
- } from "./chunk-LF2NWQ4B.js";
7
+ } from "./chunk-DNG5CRT3.js";
8
8
  import {
9
9
  ApiError
10
10
  } from "./chunk-PY74LT2W.js";
@@ -13,7 +13,7 @@ import {
13
13
  CLI_INSTALL_COMMAND,
14
14
  cliNpxCommand,
15
15
  defaultCtx
16
- } from "./chunk-TH4ANHSG.js";
16
+ } from "./chunk-ZC2DAKB5.js";
17
17
  import "./chunk-K3NQKI34.js";
18
18
 
19
19
  // src/cli.ts
@@ -59,27 +59,27 @@ async function run(argv, ctx = defaultCtx()) {
59
59
  try {
60
60
  switch (cmd) {
61
61
  case "connect":
62
- return await (await import("./connect-TG2H5SMB.js")).connect(ctx, p);
62
+ return await (await import("./connect-ACNM5DQG.js")).connect(ctx, p);
63
63
  case "disconnect":
64
- return await (await import("./disconnect-FI76IEZJ.js")).disconnect(ctx, p);
64
+ return await (await import("./disconnect-MKRHK4CX.js")).disconnect(ctx, p);
65
65
  case "status":
66
- return await (await import("./status-SMAVPW4D.js")).status(ctx, p);
66
+ return await (await import("./status-KBBSAADD.js")).status(ctx, p);
67
67
  case "where":
68
- return await (await import("./where-7NI7UEEF.js")).where(ctx, p);
68
+ return await (await import("./where-KR7VWSEC.js")).where(ctx, p);
69
69
  case "service":
70
70
  if (p.positionals[0] !== "run") {
71
71
  ctx.err("hivefloor: usage: hivefloor service run\n");
72
72
  return 2;
73
73
  }
74
- return await (await import("./run-CKNHDPNX.js")).runService({ ctx });
74
+ return await (await import("./run-336BSU72.js")).runService({ ctx });
75
75
  case "link":
76
- return await (await import("./link-JX4YLF2Z.js")).link(ctx, p);
76
+ return await (await import("./link-HXBMMSG3.js")).link(ctx, p);
77
77
  case "token":
78
- return await (await import("./token-AUEAWQDH.js")).token(ctx, p);
78
+ return await (await import("./token-JDRLEV5D.js")).token(ctx, p);
79
79
  case "mcp":
80
- return await (await import("./mcp-EUBTVJNX.js")).runMcpProxy(ctx, p);
80
+ return await (await import("./mcp-N2TMD4GR.js")).runMcpProxy(ctx, p);
81
81
  case "hook": {
82
- const { runHook, readStdin } = await import("./hook-N4ZTQEWM.js");
82
+ const { runHook, readStdin } = await import("./hook-KR2HGVAR.js");
83
83
  await runHook(rest, { env: ctx.env, cwd: ctx.cwd, fetch: ctx.fetch, now: ctx.now, readStdin });
84
84
  return 0;
85
85
  }
@@ -3,18 +3,18 @@ import {
3
3
  connect,
4
4
  connectAgent,
5
5
  resolveHost
6
- } from "./chunk-OOMBZN4M.js";
7
- import "./chunk-HT5KXWXM.js";
8
- import "./chunk-NLZXB26Y.js";
9
- import "./chunk-YRNMECUF.js";
6
+ } from "./chunk-SD65CIIY.js";
7
+ import "./chunk-R5KDI4WI.js";
8
+ import "./chunk-QHYZBHXO.js";
9
+ import "./chunk-2BSA7LFD.js";
10
10
  import "./chunk-2IMJECYD.js";
11
11
  import "./chunk-TKMIV7BG.js";
12
- import "./chunk-DQV6FAJU.js";
13
- import "./chunk-LF2NWQ4B.js";
12
+ import "./chunk-PDXYOREI.js";
13
+ import "./chunk-DNG5CRT3.js";
14
14
  import "./chunk-T7TG6WA4.js";
15
15
  import "./chunk-PY74LT2W.js";
16
16
  import "./chunk-VNCQFFQO.js";
17
- import "./chunk-TH4ANHSG.js";
17
+ import "./chunk-ZC2DAKB5.js";
18
18
  import "./chunk-K3NQKI34.js";
19
19
  export {
20
20
  connect,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  removeCliCopy,
4
4
  removeMachineHooks
5
- } from "./chunk-NKMVO5BP.js";
5
+ } from "./chunk-GT3HFFT4.js";
6
6
  import {
7
7
  claudeJson,
8
8
  geminiSettings,
@@ -14,7 +14,7 @@ import {
14
14
  removeGrok,
15
15
  removeRcLine,
16
16
  updateManifest
17
- } from "./chunk-NLZXB26Y.js";
17
+ } from "./chunk-QHYZBHXO.js";
18
18
  import {
19
19
  REAL_TOOLS,
20
20
  TOOL_LABEL,
@@ -28,8 +28,8 @@ import {
28
28
  deleteCredentials,
29
29
  readCredentials,
30
30
  uninstallService
31
- } from "./chunk-DQV6FAJU.js";
32
- import "./chunk-E4V47VEV.js";
31
+ } from "./chunk-PDXYOREI.js";
32
+ import "./chunk-UJ4BQFWV.js";
33
33
  import {
34
34
  readMachine,
35
35
  removeMachineFile
@@ -48,7 +48,7 @@ import {
48
48
  import {
49
49
  normalizeHost,
50
50
  runCmd
51
- } from "./chunk-TH4ANHSG.js";
51
+ } from "./chunk-ZC2DAKB5.js";
52
52
  import "./chunk-K3NQKI34.js";
53
53
 
54
54
  // src/disconnect.ts
@@ -4,11 +4,11 @@ import {
4
4
  } from "./chunk-JCLWCMEM.js";
5
5
  import {
6
6
  detectRepo
7
- } from "./chunk-YRNMECUF.js";
7
+ } from "./chunk-2BSA7LFD.js";
8
8
  import {
9
9
  defaultHost,
10
10
  loadToken
11
- } from "./chunk-DQV6FAJU.js";
11
+ } from "./chunk-PDXYOREI.js";
12
12
  import {
13
13
  appendToSpool,
14
14
  contextEventName,
@@ -31,9 +31,10 @@ import {
31
31
  DEFAULT_HOST,
32
32
  HOOK_BATCH_MAX,
33
33
  PROFILE_KEY_RE,
34
+ SESSION_ACCOUNT_RE,
34
35
  hostFromEnv,
35
36
  redact
36
- } from "./chunk-TH4ANHSG.js";
37
+ } from "./chunk-ZC2DAKB5.js";
37
38
  import "./chunk-K3NQKI34.js";
38
39
 
39
40
  // src/hook.ts
@@ -223,7 +224,8 @@ async function runHookInner(args, deps, startedAt) {
223
224
  const repo = await detectRepo(cwdOf(input) ?? deps.cwd);
224
225
  if (repo) event.repo = { remote: repo.remote, ...repo.branch ? { branch: repo.branch } : {}, ...repo.path ? { path: repo.path } : {} };
225
226
  if (machine && profile !== void 0) {
226
- const mevent = { ...event, profile };
227
+ const account = deps.env.FLEET_PROFILE?.trim();
228
+ const mevent = { ...event, profile, ...account && SESSION_ACCOUNT_RE.test(account) ? { account } : {} };
227
229
  if (serviceAlive(deps.now())) {
228
230
  appendToSpool(mevent, machineSpoolFile());
229
231
  if (contextName) nudges.push(...takeStashed(event.session_id, nowMs).map((text) => ({ session_id: event.session_id, text })));
package/dist/index.js CHANGED
@@ -11,12 +11,12 @@ if (argv[0] === "hook") {
11
11
  process.on("unhandledRejection", () => process.exit(0));
12
12
  setTimeout(() => process.exit(0), HARD_EXIT_MS).unref();
13
13
  try {
14
- const { runHookCli } = await import("./hook-N4ZTQEWM.js");
14
+ const { runHookCli } = await import("./hook-KR2HGVAR.js");
15
15
  await runHookCli(argv.slice(1));
16
16
  } catch {
17
17
  }
18
18
  process.exit(0);
19
19
  } else {
20
- const { run } = await import("./cli-F3F7SQLV.js");
20
+ const { run } = await import("./cli-P3DYE5IR.js");
21
21
  process.exitCode = await run(argv);
22
22
  }
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  deviceLogin
4
- } from "./chunk-HT5KXWXM.js";
4
+ } from "./chunk-R5KDI4WI.js";
5
5
  import {
6
6
  detectRepo
7
- } from "./chunk-YRNMECUF.js";
7
+ } from "./chunk-2BSA7LFD.js";
8
8
  import {
9
9
  resolveSession
10
- } from "./chunk-DWHMBUCA.js";
10
+ } from "./chunk-7KF7IQJN.js";
11
11
  import {
12
12
  isTool
13
13
  } from "./chunk-2IMJECYD.js";
@@ -16,10 +16,10 @@ import {
16
16
  } from "./chunk-TKMIV7BG.js";
17
17
  import {
18
18
  saveToken
19
- } from "./chunk-DQV6FAJU.js";
19
+ } from "./chunk-PDXYOREI.js";
20
20
  import {
21
21
  VERSION
22
- } from "./chunk-LF2NWQ4B.js";
22
+ } from "./chunk-DNG5CRT3.js";
23
23
  import {
24
24
  apiRequest,
25
25
  errorOf
@@ -28,7 +28,7 @@ import "./chunk-VNCQFFQO.js";
28
28
  import {
29
29
  cliNpxCommand,
30
30
  machineName
31
- } from "./chunk-TH4ANHSG.js";
31
+ } from "./chunk-ZC2DAKB5.js";
32
32
  import "./chunk-K3NQKI34.js";
33
33
 
34
34
  // src/link.ts
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  resolveHost
4
- } from "./chunk-OOMBZN4M.js";
4
+ } from "./chunk-SD65CIIY.js";
5
5
  import {
6
6
  deviceLogin
7
- } from "./chunk-HT5KXWXM.js";
7
+ } from "./chunk-R5KDI4WI.js";
8
8
  import {
9
9
  installCliCopy,
10
10
  installMachineHooks
11
- } from "./chunk-NKMVO5BP.js";
12
- import "./chunk-NLZXB26Y.js";
13
- import "./chunk-YRNMECUF.js";
11
+ } from "./chunk-GT3HFFT4.js";
12
+ import "./chunk-QHYZBHXO.js";
13
+ import "./chunk-2BSA7LFD.js";
14
14
  import {
15
15
  findBin
16
16
  } from "./chunk-2IMJECYD.js";
@@ -20,18 +20,18 @@ import {
20
20
  import {
21
21
  installService,
22
22
  windowsUser
23
- } from "./chunk-DQV6FAJU.js";
23
+ } from "./chunk-PDXYOREI.js";
24
24
  import {
25
25
  claudeDirsOfScan,
26
26
  cliVersionOs,
27
27
  scanProcesses
28
- } from "./chunk-O6VSA2JT.js";
28
+ } from "./chunk-W7DROKC7.js";
29
29
  import {
30
30
  VERSION
31
- } from "./chunk-LF2NWQ4B.js";
31
+ } from "./chunk-DNG5CRT3.js";
32
32
  import {
33
33
  codexConfigDir
34
- } from "./chunk-E4V47VEV.js";
34
+ } from "./chunk-UJ4BQFWV.js";
35
35
  import {
36
36
  readMachine,
37
37
  secureWindowsMachine,
@@ -47,7 +47,7 @@ import {
47
47
  machineTokenSuccessSchema,
48
48
  normalizeHost,
49
49
  runCmd
50
- } from "./chunk-TH4ANHSG.js";
50
+ } from "./chunk-ZC2DAKB5.js";
51
51
  import "./chunk-K3NQKI34.js";
52
52
 
53
53
  // src/machine-connect.ts
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  detectRepo
4
- } from "./chunk-YRNMECUF.js";
4
+ } from "./chunk-2BSA7LFD.js";
5
5
  import {
6
6
  resolveSession
7
- } from "./chunk-DWHMBUCA.js";
7
+ } from "./chunk-7KF7IQJN.js";
8
8
  import {
9
9
  toolFromEnv
10
10
  } from "./chunk-2IMJECYD.js";
@@ -13,13 +13,13 @@ import {
13
13
  } from "./chunk-TKMIV7BG.js";
14
14
  import {
15
15
  loadToken
16
- } from "./chunk-DQV6FAJU.js";
16
+ } from "./chunk-PDXYOREI.js";
17
17
  import "./chunk-VNCQFFQO.js";
18
18
  import {
19
19
  cliNpxCommand,
20
20
  isSecureUrl,
21
21
  normalizeHost
22
- } from "./chunk-TH4ANHSG.js";
22
+ } from "./chunk-ZC2DAKB5.js";
23
23
  import "./chunk-K3NQKI34.js";
24
24
 
25
25
  // src/mcp.ts
@@ -10,16 +10,16 @@ import {
10
10
  cliVersionOs,
11
11
  makeEnvReader,
12
12
  scanProcesses
13
- } from "./chunk-O6VSA2JT.js";
13
+ } from "./chunk-W7DROKC7.js";
14
14
  import {
15
15
  VERSION
16
- } from "./chunk-LF2NWQ4B.js";
16
+ } from "./chunk-DNG5CRT3.js";
17
17
  import {
18
18
  claudeDirsFromRc,
19
19
  profileKeyOf,
20
20
  profileKeys,
21
21
  uniqueProfileKey
22
- } from "./chunk-E4V47VEV.js";
22
+ } from "./chunk-UJ4BQFWV.js";
23
23
  import {
24
24
  readMachine,
25
25
  writeMachine,
@@ -44,7 +44,7 @@ import {
44
44
  parseUsageKey,
45
45
  runCmd,
46
46
  usageReadingSchema
47
- } from "./chunk-TH4ANHSG.js";
47
+ } from "./chunk-ZC2DAKB5.js";
48
48
  import "./chunk-K3NQKI34.js";
49
49
 
50
50
  // src/service/run.ts
@@ -859,6 +859,7 @@ var readClaude = async (deps) => {
859
859
  const out = emptyOutput();
860
860
  const seenTokens = /* @__PURE__ */ new Set();
861
861
  const seenLabels = /* @__PURE__ */ new Set();
862
+ const readLabels = /* @__PURE__ */ new Set();
862
863
  for (const dir of claudeConfigDirs(deps)) {
863
864
  let raw = deps.readFile(joinPath(dir, ".credentials.json"));
864
865
  if (raw === null && deps.platform === "darwin" && deps.exec) {
@@ -875,7 +876,7 @@ var readClaude = async (deps) => {
875
876
  if (creds.kind === "none") continue;
876
877
  seenLabels.add(label);
877
878
  if (creds.kind === "expired") {
878
- out.issues.push(issue("claude", label, "expired", issueMessage("expired")));
879
+ out.issues.push(issue("claude", label, "expired", "The saved login is out of date (no Claude session used it lately). It updates the next time Claude Code runs on this profile."));
879
880
  continue;
880
881
  }
881
882
  if (creds.kind === "no_scope") {
@@ -884,50 +885,155 @@ var readClaude = async (deps) => {
884
885
  }
885
886
  if (seenTokens.has(creds.token)) continue;
886
887
  seenTokens.add(creds.token);
887
- const headers = {
888
- Authorization: `Bearer ${creds.token}`,
889
- "anthropic-beta": "oauth-2025-04-20",
890
- "anthropic-version": "2023-06-01",
891
- Accept: "application/json"
892
- };
893
888
  try {
894
- const parsed = parseClaudeUsage(await requestJson(deps, USAGE_URL, { headers }));
895
- parsed.plan = creds.plan;
896
- try {
897
- const profile = asRecord(await requestJson(deps, PROFILE_URL, { headers }));
898
- const account = asRecord(profile?.account) ?? profile;
899
- parsed.accountId = asString(account?.uuid) ?? asString(account?.id);
900
- const org = asRecord(profile?.organization);
901
- parsed.plan ??= planName(asString(org?.organization_type) ?? asString(org?.rate_limit_tier));
902
- } catch {
903
- }
904
- if (parsed.windows.length === 0) throw new ReaderError("bad_response", issueMessage("bad_response"));
889
+ const parsed = await readTokenUsage(deps, creds.token);
890
+ parsed.plan ??= creds.plan;
905
891
  out.readings.push(...toReadings("claude", label, parsed, "local_login"));
892
+ readLabels.add(label);
906
893
  } catch (e) {
907
894
  out.issues.push(failure("claude", label, e));
908
895
  }
909
896
  }
897
+ await readNamedTokens(deps, seenTokens, readLabels, out);
910
898
  await readEnvTokens(deps, seenTokens, out);
911
899
  return out;
912
900
  };
901
+ var CLAUDE_HEADERS = (token) => ({
902
+ Authorization: `Bearer ${token}`,
903
+ "anthropic-beta": "oauth-2025-04-20",
904
+ "anthropic-version": "2023-06-01",
905
+ Accept: "application/json"
906
+ });
907
+ async function readTokenUsage(deps, token) {
908
+ const headers = CLAUDE_HEADERS(token);
909
+ let parsed;
910
+ try {
911
+ parsed = parseClaudeUsage(await requestJson(deps, USAGE_URL, { headers }));
912
+ if (parsed.windows.length === 0) throw new ReaderError("bad_response", issueMessage("bad_response"));
913
+ } catch (e) {
914
+ if (!(e instanceof ReaderError) || e.code !== "rejected" && e.code !== "rate_limited") throw e;
915
+ return probeRateLimits(deps, token);
916
+ }
917
+ try {
918
+ const profile = asRecord(await requestJson(deps, PROFILE_URL, { headers }));
919
+ const account = asRecord(profile?.account) ?? profile;
920
+ parsed.accountId = asString(account?.uuid) ?? asString(account?.id);
921
+ const org = asRecord(profile?.organization);
922
+ parsed.plan ??= planName(asString(org?.organization_type) ?? asString(org?.rate_limit_tier));
923
+ } catch {
924
+ }
925
+ return parsed;
926
+ }
927
+ var PROBE_URL = "https://api.anthropic.com/v1/messages";
928
+ var PROBE_MODEL = "claude-haiku-5-5";
929
+ var PROBE_TTL_MS = 15 * 6e4;
930
+ var probeCache = /* @__PURE__ */ new Map();
931
+ function parseClaudeRateHeaders(h) {
932
+ const windows = [];
933
+ const names = {
934
+ "5h": ["5h", "5 hours"],
935
+ "7d": ["weekly", "Weekly"],
936
+ "7d_opus": ["weekly:opus", "Opus weekly"],
937
+ "7d_sonnet": ["weekly:sonnet", "Sonnet weekly"]
938
+ };
939
+ for (const [key, value] of Object.entries(h)) {
940
+ const m = /^anthropic-ratelimit-unified-([a-z0-9_]+)-utilization$/.exec(key.toLowerCase());
941
+ if (!m) continue;
942
+ const id = m[1];
943
+ const util = asNumber(Number(value));
944
+ if (util === void 0) continue;
945
+ const [window, label] = names[id] ?? (/^7d_[a-z0-9]+$/.test(id) ? [`weekly:${slug(id.slice(3))}`, `${id.slice(3)} weekly`] : [`${slug(id)}`, id]);
946
+ if (!/^[a-z0-9]+(?::[a-z0-9._-]+)?$/.test(window)) continue;
947
+ addWin(windows, { window, label, percent: util * 100, resets: h[`anthropic-ratelimit-unified-${id}-reset`] });
948
+ }
949
+ windows.sort((a, b) => a.window === "5h" ? -1 : b.window === "5h" ? 1 : a.window.localeCompare(b.window));
950
+ return { windows };
951
+ }
952
+ async function probeRateLimits(deps, token) {
953
+ const key = tokenLabel(token);
954
+ const cached = probeCache.get(key);
955
+ if (cached && deps.now() - cached.at < PROBE_TTL_MS) return { ...cached.parsed, windows: [...cached.parsed.windows] };
956
+ const model = /^[a-z0-9.-]{3,60}$/.test(deps.env.HIVEFLOOR_CLAUDE_PROBE_MODEL ?? "") ? deps.env.HIVEFLOOR_CLAUDE_PROBE_MODEL : PROBE_MODEL;
957
+ let res;
958
+ try {
959
+ res = await deps.fetch(PROBE_URL, {
960
+ method: "POST",
961
+ headers: { ...CLAUDE_HEADERS(token), "content-type": "application/json" },
962
+ body: JSON.stringify({
963
+ model,
964
+ max_tokens: 1,
965
+ system: "You are Claude Code, Anthropic's official CLI for Claude.",
966
+ messages: [{ role: "user", content: "hi" }]
967
+ })
968
+ });
969
+ await res.text();
970
+ } catch {
971
+ throw new ReaderError("unreachable", issueMessage("unreachable"));
972
+ }
973
+ const parsed = parseClaudeRateHeaders(res.headers ?? {});
974
+ if (parsed.windows.length > 0) {
975
+ probeCache.set(key, { at: deps.now(), parsed });
976
+ return parsed;
977
+ }
978
+ if (res.status === 401 || res.status === 403) throw new ReaderError("rejected", issueMessage("rejected"));
979
+ if (res.status === 429) throw new ReaderError("rate_limited", issueMessage("rate_limited"));
980
+ if (res.status >= 500) throw new ReaderError("unreachable", issueMessage("unreachable"));
981
+ throw new ReaderError("bad_response", issueMessage("bad_response"));
982
+ }
913
983
  var MAX_SESSION_TOKENS = 20;
984
+ var NAME_RE = /^[A-Za-z0-9._-]{1,40}$/;
914
985
  var tokenLabel = (token) => `token-${createHash2("sha256").update(token).digest("hex").slice(0, 6)}`;
986
+ function claudeTokenProfiles(deps) {
987
+ const names = /* @__PURE__ */ new Set();
988
+ const add = (n) => {
989
+ if (NAME_RE.test(n) && n !== "api") names.add(n);
990
+ };
991
+ for (const f of deps.readDir(joinPath(deps.home, ".config/fleet-cc")).sort()) {
992
+ const m = /^(.+)\.token$/.exec(f);
993
+ if (m) add(m[1]);
994
+ }
995
+ for (const d of deps.readDir(deps.home).sort()) {
996
+ const m = /^\.claude-([A-Za-z0-9._-]+)$/.exec(d);
997
+ if (m) add(m[1]);
998
+ }
999
+ const cc = deps.readFile(joinPath(deps.home, ".claude/fleet/cc.sh"));
1000
+ const line = cc ? /^PROFILES="([^"\n]*)"/m.exec(cc) : null;
1001
+ for (const n of (line?.[1] ?? "").split(/\s+/)) if (n) add(n);
1002
+ for (const n of (deps.env.HIVEFLOOR_CLAUDE_PROFILES ?? "").split(/[\s,]+/)) if (n) add(n);
1003
+ return [...names];
1004
+ }
1005
+ function namedToken(deps, name) {
1006
+ let t = deps.readFile(joinPath(deps.home, `.config/fleet-cc/${name}.token`));
1007
+ if ((t === null || t.trim() === "") && deps.platform === "darwin" && deps.exec) {
1008
+ t = deps.exec("security", ["find-generic-password", "-s", `fleet-cc-${name}`, "-w"]);
1009
+ }
1010
+ const v = t?.trim() ?? "";
1011
+ return /^[\w.~+/=-]{20,400}$/.test(v) ? v : null;
1012
+ }
1013
+ async function readNamedTokens(deps, seenTokens, readLabels, out) {
1014
+ for (const name of claudeTokenProfiles(deps)) {
1015
+ if (readLabels.has(name)) continue;
1016
+ const token = namedToken(deps, name);
1017
+ if (!token || seenTokens.has(token)) continue;
1018
+ seenTokens.add(token);
1019
+ try {
1020
+ const parsed = await readTokenUsage(deps, token);
1021
+ out.readings.push(...toReadings("claude", name, parsed, "local_login"));
1022
+ readLabels.add(name);
1023
+ out.issues = out.issues.filter((i) => !(i.provider === "claude" && i.account_label === name));
1024
+ } catch (e) {
1025
+ if (!out.issues.some((i) => i.provider === "claude" && i.account_label === name)) out.issues.push(failure("claude", name, e));
1026
+ }
1027
+ }
1028
+ }
915
1029
  async function readEnvTokens(deps, seenTokens, out) {
916
1030
  const tokens = [...new Set(deps.claudeTokens ?? [])].filter((t) => t.length >= 20 && !seenTokens.has(t)).slice(0, MAX_SESSION_TOKENS);
917
1031
  let blind = 0;
918
1032
  for (const token of tokens) {
919
1033
  seenTokens.add(token);
920
1034
  const label = tokenLabel(token);
921
- const headers = { Authorization: `Bearer ${token}`, "anthropic-beta": "oauth-2025-04-20", "anthropic-version": "2023-06-01", Accept: "application/json" };
922
1035
  try {
923
- const parsed = parseClaudeUsage(await requestJson(deps, USAGE_URL, { headers }));
924
- try {
925
- const profile = asRecord(await requestJson(deps, PROFILE_URL, { headers }));
926
- const account = asRecord(profile?.account) ?? profile;
927
- parsed.accountId = asString(account?.uuid) ?? asString(account?.id);
928
- } catch {
929
- }
930
- if (parsed.windows.length === 0) throw new ReaderError("bad_response", issueMessage("bad_response"));
1036
+ const parsed = await readTokenUsage(deps, token);
931
1037
  out.readings.push(...toReadings("claude", label, parsed, "env_key"));
932
1038
  } catch (e) {
933
1039
  if (e instanceof ReaderError && e.code === "rejected") blind++;
@@ -1627,7 +1733,7 @@ function nodeDeps() {
1627
1733
  return {
1628
1734
  async fetch(url, init = {}) {
1629
1735
  const res = await fetch(url, { method: init.method ?? "GET", headers: init.headers, body: init.body, redirect: "manual", signal: AbortSignal.timeout(TIMEOUT_MS) });
1630
- return { status: res.status, text: () => res.text() };
1736
+ return { status: res.status, text: () => res.text(), headers: Object.fromEntries([...res.headers].map(([k, v]) => [k.toLowerCase(), v])) };
1631
1737
  },
1632
1738
  readFile,
1633
1739
  readDir(path2) {
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  detectRepo
4
- } from "./chunk-YRNMECUF.js";
4
+ } from "./chunk-2BSA7LFD.js";
5
5
  import {
6
6
  resolveSession
7
- } from "./chunk-DWHMBUCA.js";
7
+ } from "./chunk-7KF7IQJN.js";
8
8
  import "./chunk-2IMJECYD.js";
9
9
  import "./chunk-TKMIV7BG.js";
10
10
  import {
11
11
  SCHTASKS_TASK,
12
12
  readCredentials,
13
13
  windowsServiceStatus
14
- } from "./chunk-DQV6FAJU.js";
14
+ } from "./chunk-PDXYOREI.js";
15
15
  import {
16
16
  profileKeys
17
- } from "./chunk-E4V47VEV.js";
17
+ } from "./chunk-UJ4BQFWV.js";
18
18
  import {
19
19
  SERVICE_ALIVE_MS,
20
20
  readMachine,
@@ -29,7 +29,7 @@ import {
29
29
  cliNpxCommand,
30
30
  machineName,
31
31
  runCmd
32
- } from "./chunk-TH4ANHSG.js";
32
+ } from "./chunk-ZC2DAKB5.js";
33
33
  import "./chunk-K3NQKI34.js";
34
34
 
35
35
  // src/status.ts
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  resolveSession
4
- } from "./chunk-DWHMBUCA.js";
4
+ } from "./chunk-7KF7IQJN.js";
5
5
  import "./chunk-2IMJECYD.js";
6
6
  import "./chunk-TKMIV7BG.js";
7
- import "./chunk-DQV6FAJU.js";
7
+ import "./chunk-PDXYOREI.js";
8
8
  import "./chunk-VNCQFFQO.js";
9
9
  import {
10
10
  cliNpxCommand
11
- } from "./chunk-TH4ANHSG.js";
11
+ } from "./chunk-ZC2DAKB5.js";
12
12
  import "./chunk-K3NQKI34.js";
13
13
 
14
14
  // src/token.ts
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  resolveSession
4
- } from "./chunk-DWHMBUCA.js";
4
+ } from "./chunk-7KF7IQJN.js";
5
5
  import "./chunk-2IMJECYD.js";
6
6
  import "./chunk-TKMIV7BG.js";
7
- import "./chunk-DQV6FAJU.js";
7
+ import "./chunk-PDXYOREI.js";
8
8
  import {
9
9
  apiRequest,
10
10
  errorOf
@@ -14,7 +14,7 @@ import {
14
14
  cliNpxCommand,
15
15
  routeProviderFromParam,
16
16
  usageRouteSchema
17
- } from "./chunk-TH4ANHSG.js";
17
+ } from "./chunk-ZC2DAKB5.js";
18
18
  import "./chunk-K3NQKI34.js";
19
19
 
20
20
  // src/where.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hivefloor/cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Connect your coding agents (Claude Code, Codex, Cursor, Gemini, Grok) to Hivefloor: live presence, task coordination and usage on one floor.",
5
5
  "author": {
6
6
  "name": "Errr0rr404",