@hivefloor/cli 0.1.5 → 0.1.8

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 (48) hide show
  1. package/LICENSE +6 -20
  2. package/README.md +29 -8
  3. package/dist/chunk-2ERPDCOT.js +38 -0
  4. package/dist/chunk-4G362W6G.js +19 -0
  5. package/dist/chunk-5OJUJCE3.js +817 -0
  6. package/dist/{chunk-U6RRUAC2.js → chunk-5XXYQQG6.js} +53 -8
  7. package/dist/chunk-AGIYVFDQ.js +10984 -0
  8. package/dist/{chunk-RYGL6XU4.js → chunk-BLLPDPTL.js} +4 -2
  9. package/dist/{chunk-3N5JYP5O.js → chunk-FPJNGKT5.js} +5 -3
  10. package/dist/chunk-HW3KRNCO.js +201 -0
  11. package/dist/{chunk-4DRHR7LR.js → chunk-HWBUESB4.js} +1158 -196
  12. package/dist/{chunk-C627OKTW.js → chunk-K2IRTZH5.js} +7 -6
  13. package/dist/chunk-KQMPCV57.js +122 -0
  14. package/dist/{chunk-J36OIJBM.js → chunk-L6EFW2SJ.js} +14 -10
  15. package/dist/{chunk-IJRHCDIG.js → chunk-LX5A25O6.js} +4 -2
  16. package/dist/{chunk-MZGGJ6ZS.js → chunk-MYJCU5JL.js} +4 -2
  17. package/dist/{chunk-H6NYMF2D.js → chunk-NMUH5NXN.js} +6 -4
  18. package/dist/{chunk-VX7SCIF2.js → chunk-NRJONTFT.js} +3 -1
  19. package/dist/chunk-QBBKGORP.js +327 -0
  20. package/dist/{chunk-SOXRITAW.js → chunk-QGULSOQ2.js} +3 -0
  21. package/dist/{chunk-6MDJB3BV.js → chunk-QLMLB7RB.js} +17 -9
  22. package/dist/{chunk-TKMIV7BG.js → chunk-QPAFN47B.js} +3 -1
  23. package/dist/chunk-SBOEAOHD.js +48 -0
  24. package/dist/{chunk-IWIDKNWC.js → chunk-TIR4CV3P.js} +21 -17
  25. package/dist/{chunk-6XVIEX75.js → chunk-X2KH6AR4.js} +25 -303
  26. package/dist/chunk-XAXKZ572.js +106 -0
  27. package/dist/{chunk-TPMFQUAW.js → chunk-XPGL7VYE.js} +12 -0
  28. package/dist/{cli-JCBZICR3.js → cli-BFOJWJNG.js} +56 -20
  29. package/dist/connect-ZJ4JXBAJ.js +27 -0
  30. package/dist/control-6GHTZQJV.js +25 -0
  31. package/dist/{disconnect-WQMDCUXT.js → disconnect-3T25NTKX.js} +24 -17
  32. package/dist/{hook-AYJNRGIY.js → hook-TPSHBCWU.js} +277 -17
  33. package/dist/index.js +9 -6
  34. package/dist/{link-ORT4LID6.js → link-EAS5F5PC.js} +14 -11
  35. package/dist/{machine-connect-N52CKQEW.js → machine-connect-KEI4BRWF.js} +23 -17
  36. package/dist/mcp-LVIYR3EN.js +1882 -0
  37. package/dist/orch-KVRL2YA2.js +137 -0
  38. package/dist/{run-ZAZ45MKQ.js → run-JL2OZWK3.js} +1920 -28
  39. package/dist/{status-GOCFNO7K.js → status-QXOOJGGN.js} +14 -11
  40. package/dist/{token-EMM4AJAU.js → token-BFWWQIDA.js} +10 -7
  41. package/dist/{voice-F5MIS3IZ.js → voice-QXHFXRWG.js} +5 -3
  42. package/dist/{where-XFXRTP7E.js → where-CMUORQIO.js} +11 -8
  43. package/package.json +5 -6
  44. package/dist/chunk-JCLWCMEM.js +0 -8
  45. package/dist/chunk-K3NQKI34.js +0 -10
  46. package/dist/chunk-X6B6R32A.js +0 -303
  47. package/dist/connect-2HLVPEOL.js +0 -23
  48. package/dist/mcp-2SF6Y73M.js +0 -118
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire as __hfCreateRequire } from 'node:module';
3
+ const require = __hfCreateRequire(import.meta.url);
2
4
  import {
3
5
  __export
4
- } from "./chunk-K3NQKI34.js";
6
+ } from "./chunk-2ERPDCOT.js";
5
7
 
6
8
  // ../../node_modules/.pnpm/zod@4.6.7/node_modules/zod/v4/classic/external.js
7
9
  var external_exports = {};
@@ -838,14 +840,14 @@ function promiseAllObject(promisesObj) {
838
840
  }
839
841
  function randomString(length = 10) {
840
842
  const chars = "abcdefghijklmnopqrstuvwxyz";
841
- let str = "";
843
+ let str2 = "";
842
844
  for (let i = 0; i < length; i++) {
843
- str += chars[Math.floor(Math.random() * chars.length)];
845
+ str2 += chars[Math.floor(Math.random() * chars.length)];
844
846
  }
845
- return str;
847
+ return str2;
846
848
  }
847
- function esc(str) {
848
- return JSON.stringify(str);
849
+ function esc(str2) {
850
+ return JSON.stringify(str2);
849
851
  }
850
852
  function slugify(input2) {
851
853
  return input2.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
@@ -959,8 +961,8 @@ var primitiveTypes = /* @__PURE__ */ new Set([
959
961
  "symbol",
960
962
  "undefined"
961
963
  ]);
962
- function escapeRegex(str) {
963
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
964
+ function escapeRegex(str2) {
965
+ return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
964
966
  }
965
967
  function clone(inst, def, params) {
966
968
  const cl = new inst._zod.constr(def ?? inst._zod.def);
@@ -1226,13 +1228,13 @@ function getSizableOrigin(input2) {
1226
1228
  return "unknown";
1227
1229
  }
1228
1230
  var highSurrogate = /[\uD800-\uDBFF]/;
1229
- function codePointLength(str) {
1230
- const units = str.length;
1231
- if (!highSurrogate.test(str))
1231
+ function codePointLength(str2) {
1232
+ const units = str2.length;
1233
+ if (!highSurrogate.test(str2))
1232
1234
  return units;
1233
1235
  let count = units;
1234
1236
  for (let i = 0; i < units - 1; i++) {
1235
- if ((str.charCodeAt(i) & 64512) === 55296 && (str.charCodeAt(i + 1) & 64512) === 56320) {
1237
+ if ((str2.charCodeAt(i) & 64512) === 55296 && (str2.charCodeAt(i + 1) & 64512) === 56320) {
1236
1238
  count--;
1237
1239
  i++;
1238
1240
  }
@@ -3621,15 +3623,15 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
3621
3623
  const syms = normalized.symbolKeys;
3622
3624
  const doc = new Doc(["payload", "ctx"], { shape, inst, memo: memo2, syms });
3623
3625
  const parseStr = (k) => `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
3624
- const prefixStr = (id, k) => `
3625
- let ${id}_ab = false;
3626
- for (let i = 0; i < ${id}.issues.length; i++) {
3627
- const iss = ${id}.issues[i];
3626
+ const prefixStr = (id2, k) => `
3627
+ let ${id2}_ab = false;
3628
+ for (let i = 0; i < ${id2}.issues.length; i++) {
3629
+ const iss = ${id2}.issues[i];
3628
3630
  iss.path = iss.path ? [${k}, ...iss.path] : [${k}];
3629
3631
  payload.issues.push(iss);
3630
- if (iss.continue !== true) ${id}_ab = true;
3632
+ if (iss.continue !== true) ${id2}_ab = true;
3631
3633
  }
3632
- if (${id}_ab && ctx && ctx.abortEarly) {
3634
+ if (${id2}_ab && ctx && ctx.abortEarly) {
3633
3635
  payload.value = newResult;
3634
3636
  return payload;
3635
3637
  }`;
@@ -3643,34 +3645,34 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
3643
3645
  for (const key2 of normalized.allKeys) {
3644
3646
  if (key2 === "__proto__")
3645
3647
  continue;
3646
- const id = ids[key2];
3648
+ const id2 = ids[key2];
3647
3649
  const k = typeof key2 === "symbol" ? `syms[${syms.indexOf(key2)}]` : esc(key2);
3648
3650
  const isPresent = `${k} in input`;
3649
3651
  const schema = shape[key2];
3650
3652
  const optin = schema?._zod?.optin;
3651
3653
  const isOptionalIn = optin !== void 0;
3652
3654
  const isOptionalOut = schema?._zod?.optout === "optional";
3653
- doc.write(`const ${id} = ${parseStr(k)};`);
3655
+ doc.write(`const ${id2} = ${parseStr(k)};`);
3654
3656
  if (isOptionalIn && isOptionalOut) {
3655
- const assign = optin === "optional" ? `${id}_present` : `${id}.value !== undefined || ${id}_present`;
3657
+ const assign = optin === "optional" ? `${id2}_present` : `${id2}.value !== undefined || ${id2}_present`;
3656
3658
  doc.write(`
3657
- const ${id}_present = ${isPresent};
3658
- if (!${id}.issues.length || ${id}_present) {
3659
- if (${id}.issues.length) {${prefixStr(id, k)}
3659
+ const ${id2}_present = ${isPresent};
3660
+ if (!${id2}.issues.length || ${id2}_present) {
3661
+ if (${id2}.issues.length) {${prefixStr(id2, k)}
3660
3662
  }
3661
3663
 
3662
3664
  if (${assign}) {
3663
- newResult[${k}] = ${id}.value;
3665
+ newResult[${k}] = ${id2}.value;
3664
3666
  }
3665
3667
  }
3666
3668
 
3667
3669
  `);
3668
3670
  } else if (!isOptionalIn) {
3669
3671
  doc.write(`
3670
- const ${id}_present = ${isPresent};
3671
- if (${id}.issues.length) {${prefixStr(id, k)}
3672
+ const ${id2}_present = ${isPresent};
3673
+ if (${id2}.issues.length) {${prefixStr(id2, k)}
3672
3674
  }
3673
- if (!${id}_present && !${id}.issues.length) {
3675
+ if (!${id2}_present && !${id2}.issues.length) {
3674
3676
  payload.issues.push({
3675
3677
  code: "invalid_type",
3676
3678
  expected: "nonoptional",
@@ -3683,22 +3685,22 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
3683
3685
  }
3684
3686
  }
3685
3687
 
3686
- if (${id}_present) {
3687
- newResult[${k}] = ${id}.value;
3688
+ if (${id2}_present) {
3689
+ newResult[${k}] = ${id2}.value;
3688
3690
  }
3689
3691
 
3690
3692
  `);
3691
3693
  } else {
3692
3694
  doc.write(`
3693
- if (${id}.issues.length) {${prefixStr(id, k)}
3695
+ if (${id2}.issues.length) {${prefixStr(id2, k)}
3694
3696
  }
3695
3697
  `);
3696
3698
  if (optin === "defaulted") {
3697
- doc.write(`newResult[${k}] = ${id}.value;`);
3699
+ doc.write(`newResult[${k}] = ${id2}.value;`);
3698
3700
  } else {
3699
3701
  doc.write(`
3700
- if (${id}.value !== undefined || ${isPresent}) {
3701
- newResult[${k}] = ${id}.value;
3702
+ if (${id2}.value !== undefined || ${isPresent}) {
3703
+ newResult[${k}] = ${id2}.value;
3702
3704
  }
3703
3705
  `);
3704
3706
  }
@@ -15726,26 +15728,26 @@ function extractDefs(ctx, schema) {
15726
15728
  return;
15727
15729
  const idToSchema = /* @__PURE__ */ new Map();
15728
15730
  for (const entry of ctx.seen.entries()) {
15729
- const id = ctx.metadataRegistry.get(entry[0])?.id;
15730
- if (id) {
15731
- const existing = idToSchema.get(id);
15731
+ const id2 = ctx.metadataRegistry.get(entry[0])?.id;
15732
+ if (id2) {
15733
+ const existing = idToSchema.get(id2);
15732
15734
  if (existing && existing !== entry[0]) {
15733
- throw new Error(`Duplicate schema id "${id}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);
15735
+ throw new Error(`Duplicate schema id "${id2}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);
15734
15736
  }
15735
- idToSchema.set(id, entry[0]);
15737
+ idToSchema.set(id2, entry[0]);
15736
15738
  }
15737
15739
  }
15738
15740
  const makeURI = (entry) => {
15739
15741
  const defsSegment = ctx.target === "draft-2020-12" ? "$defs" : "definitions";
15740
15742
  if (ctx.external) {
15741
15743
  const externalId = ctx.external.registry.get(entry[0])?.id;
15742
- const uriGenerator = ctx.external.uri ?? ((id2) => id2);
15744
+ const uriGenerator = ctx.external.uri ?? ((id3) => id3);
15743
15745
  if (externalId) {
15744
15746
  return { ref: uriGenerator(externalId) };
15745
15747
  }
15746
- const id = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;
15747
- entry[1].defId = id;
15748
- return { defId: id, ref: `${uriGenerator("__shared")}#/${defsSegment}/${encodeJSONPointerSegment(id)}` };
15748
+ const id2 = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;
15749
+ entry[1].defId = id2;
15750
+ return { defId: id2, ref: `${uriGenerator("__shared")}#/${defsSegment}/${encodeJSONPointerSegment(id2)}` };
15749
15751
  }
15750
15752
  const uriPrefix = `#`;
15751
15753
  const defUriPrefix = `${uriPrefix}/${defsSegment}/`;
@@ -15793,8 +15795,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15793
15795
  continue;
15794
15796
  }
15795
15797
  }
15796
- const id = ctx.metadataRegistry.get(entry[0])?.id;
15797
- if (id) {
15798
+ const id2 = ctx.metadataRegistry.get(entry[0])?.id;
15799
+ if (id2) {
15798
15800
  extractToDef(entry);
15799
15801
  continue;
15800
15802
  }
@@ -16027,10 +16029,10 @@ function finalize(ctx, schema) {
16027
16029
  } else {
16028
16030
  }
16029
16031
  if (ctx.external?.uri) {
16030
- const id = ctx.external.registry.get(schema)?.id;
16031
- if (!id)
16032
+ const id2 = ctx.external.registry.get(schema)?.id;
16033
+ if (!id2)
16032
16034
  throw new Error("Schema is missing an `id` property");
16033
- result.$id = ctx.external.uri(id);
16035
+ result.$id = ctx.external.uri(id2);
16034
16036
  }
16035
16037
  assignProps(result, root.defId ? root.schema : root.def ?? root.schema);
16036
16038
  const rootMetaId = ctx.metadataRegistry.get(schema)?.id;
@@ -16636,7 +16638,7 @@ function stringifyKeyNames(bySchema, json2, visited) {
16636
16638
  const values = json2.enum ?? (json2.const !== void 0 ? [json2.const] : void 0);
16637
16639
  if (!numericType && !values?.some((v) => typeof v === "number"))
16638
16640
  return json2;
16639
- const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id, ...rest } = json2;
16641
+ const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id: id2, ...rest } = json2;
16640
16642
  if (rest.enum)
16641
16643
  rest.enum = rest.enum.map((v) => typeof v === "number" ? String(v) : v);
16642
16644
  else if (typeof rest.const === "number")
@@ -19785,10 +19787,16 @@ var hookEventSchema = external_exports.object({
19785
19787
  status_line: external_exports.string().max(140).optional(),
19786
19788
  model: external_exports.string().min(1).max(200).optional(),
19787
19789
  repo: repoInfoSchema.optional(),
19790
+ /** The session's working directory as the hook reported it (a later Resume starts the tool there). */
19791
+ cwd: external_exports.string().min(1).max(500).optional(),
19788
19792
  /** ISO time on the client; display only (the server clock decides). */
19789
19793
  client_at: external_exports.iso.datetime({ offset: true }),
19790
19794
  /** The CLI sets it on the event it posts for a hook whose output the tool reads as context (Claude's UserPromptSubmit and the like): only then does the answer carry the session's pending nudges. */
19791
- deliver: external_exports.boolean().optional()
19795
+ deliver: external_exports.boolean().optional(),
19796
+ /** The agent's last message after a turn (docs/CONTROL.md 4.3), sent on `stop` when control allows replies; redacted by the CLI and again by the server. */
19797
+ reply: external_exports.string().max(2048).optional(),
19798
+ /** On `stop`: the turn ended by asking a person something (its last line is a question). The session waits on you, not idle. */
19799
+ asks: external_exports.boolean().optional()
19792
19800
  });
19793
19801
  var hookBatchSchema = external_exports.object({ events: external_exports.array(hookEventSchema).min(1).max(HOOK_BATCH_MAX) });
19794
19802
  var hookBatchResponseSchema = external_exports.object({
@@ -19801,6 +19809,10 @@ var hookBatchResponseSchema = external_exports.object({
19801
19809
  // ../shared/src/machine-health.ts
19802
19810
  var MACHINE_HEALTH_RULES = ["offline_with_claims", "disk_full", "disk_high", "memory_high", "cli_behind"];
19803
19811
 
19812
+ // ../shared/src/plan.ts
19813
+ var PLANS = ["free", "team", "company"];
19814
+ var planSchema = external_exports.enum(PLANS);
19815
+
19804
19816
  // ../shared/src/api/projects.ts
19805
19817
  var idSchema = external_exports.string().regex(/^[0-9]{1,15}$/, "must be a numeric id");
19806
19818
  var projectNameSchema = external_exports.string().trim().min(1).max(100);
@@ -19834,7 +19846,7 @@ var meProjectSchema = projectBriefSchema.extend({
19834
19846
  /** The person owns it. A key is unique per owner, so `/p/:key` prefers an owned project over a shared one with the same key. */
19835
19847
  owned: external_exports.boolean().optional()
19836
19848
  }).strict();
19837
- var meResponse = external_exports.object({ user: publicUserSchema, projects: external_exports.array(meProjectSchema) }).strict();
19849
+ var meResponse = external_exports.object({ user: publicUserSchema, projects: external_exports.array(meProjectSchema), plan: planSchema.optional() }).strict();
19838
19850
  var projectSettingsViewSchema = external_exports.looseObject({ answer_blocked: external_exports.boolean().optional() });
19839
19851
  var projectTransferSchema = external_exports.object({ to_user_id: idSchema, requested_at: isoSchema.nullable() }).strict();
19840
19852
  var projectSchema = external_exports.object({
@@ -19911,144 +19923,12 @@ var githubInstallationSchema = external_exports.object({
19911
19923
  }).strict();
19912
19924
  var githubInstallationsResponse = external_exports.object({ installations: external_exports.array(githubInstallationSchema) }).strict();
19913
19925
 
19914
- // ../shared/src/api/machines.ts
19915
- var MACHINE_HEARTBEAT_SECONDS = 30;
19916
- var MACHINE_MIN_INTERVAL_SECONDS = 15;
19917
- var MACHINE_MAX_AGENTS = 40;
19918
- var PROFILE_KEY_RE = /^[a-z0-9][a-z0-9._-]{0,39}$/;
19919
- var profileKeySchema = external_exports.string().regex(PROFILE_KEY_RE, "bad profile key");
19920
- var pct = external_exports.number().min(0).max(100);
19921
- var machineStatsSchema = external_exports.object({
19922
- cpu_pct: pct.optional(),
19923
- mem_pct: pct.optional(),
19924
- disk_pct: pct.optional(),
19925
- mem_total_mb: external_exports.number().int().min(0).max(1e8).optional(),
19926
- load1: external_exports.number().min(0).max(1e5).optional(),
19927
- gpu: external_exports.array(external_exports.object({ name: external_exports.string().max(100), util_pct: pct.optional(), mem_pct: pct.optional() }).strict()).max(8).optional(),
19928
- usage: external_exports.record(external_exports.string().max(80), external_exports.number().finite()).refine((o) => Object.keys(o).length <= 64, "at most 64 usage values").optional()
19929
- }).strict();
19930
- var machineHeartbeatBody = external_exports.object({
19931
- os: external_exports.string().trim().min(1).max(100).optional(),
19932
- cli_version: external_exports.string().trim().min(1).max(50).optional(),
19933
- stats: machineStatsSchema.optional()
19934
- }).strict();
19935
- var projectBriefSchema2 = external_exports.object({ id: external_exports.string(), key: external_exports.string(), name: external_exports.string() });
19936
- var machineHeartbeatResponseSchema = external_exports.object({
19937
- ok: external_exports.literal(true),
19938
- machine: external_exports.object({ id: external_exports.string(), name: external_exports.string() }),
19939
- projects: external_exports.array(projectBriefSchema2),
19940
- /** Seconds the service should wait before the next heartbeat. */
19941
- interval: external_exports.number().int().positive()
19942
- });
19943
- var discoveryProfileSchema = external_exports.object({
19944
- tool: toolSchema,
19945
- key: profileKeySchema,
19946
- /** For example `Claude Max (work)`; no email, no token. */
19947
- label: external_exports.string().trim().max(100).optional(),
19948
- model: external_exports.string().trim().max(200).optional(),
19949
- running: external_exports.number().int().min(0).max(500)
19950
- }).strict();
19951
- var discoveryBody = external_exports.object({ profiles: external_exports.array(discoveryProfileSchema).max(MACHINE_MAX_AGENTS) }).strict();
19952
- var SESSION_ACCOUNT_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,59}$/;
19953
- var machineHookEventSchema = hookEventSchema.extend({
19954
- profile: profileKeySchema.optional(),
19955
- account: external_exports.string().regex(SESSION_ACCOUNT_RE).optional().catch(void 0)
19956
- });
19957
- var machineHookBatchSchema = external_exports.object({ events: external_exports.array(machineHookEventSchema).min(1).max(HOOK_BATCH_MAX) });
19958
- var approveMachineBody = external_exports.object({
19959
- name: external_exports.string().trim().min(1).max(100),
19960
- project_ids: external_exports.array(idSchema).max(200).optional(),
19961
- default_project_id: idSchema.nullable().optional(),
19962
- /** Replace one of the person's own machines (listed in the preview's `reusable_machines`): its token is rotated, nothing else changes. */
19963
- machine_id: idSchema.optional()
19964
- }).strict();
19965
- var machineTokenSuccessSchema = external_exports.object({
19966
- token: external_exports.string().min(1),
19967
- machine: external_exports.object({ id: external_exports.string(), name: external_exports.string() }),
19968
- projects: external_exports.array(projectBriefSchema2)
19969
- });
19970
- var machineAgentSchema = external_exports.object({
19971
- id: external_exports.string(),
19972
- name: external_exports.string(),
19973
- tool: toolSchema,
19974
- profile: external_exports.string().nullable(),
19975
- account_label: external_exports.string().nullable(),
19976
- model: external_exports.string().nullable(),
19977
- /** Agent processes alive at the last discovery. */
19978
- running: external_exports.number().int().nonnegative(),
19979
- live_sessions: external_exports.number().int().nonnegative(),
19980
- last_seen_at: external_exports.string().nullable()
19981
- });
19982
- var machineHealthViewSchema = external_exports.object({
19983
- level: external_exports.enum(["warn", "critical"]),
19984
- findings: external_exports.array(external_exports.object({ rule: external_exports.enum(MACHINE_HEALTH_RULES), level: external_exports.enum(["warn", "critical"]), text: external_exports.string() }))
19985
- });
19986
- var machineSchema = external_exports.object({
19987
- id: external_exports.string(),
19988
- name: external_exports.string(),
19989
- os: external_exports.string().nullable(),
19990
- cli_version: external_exports.string().nullable(),
19991
- online: external_exports.boolean(),
19992
- last_seen_at: external_exports.string().nullable(),
19993
- created_at: external_exports.string(),
19994
- default_project_id: external_exports.string().nullable(),
19995
- projects: external_exports.array(external_exports.object({ id: external_exports.string(), key: external_exports.string(), name: external_exports.string(), default: external_exports.boolean() })),
19996
- stats: machineStatsSchema.nullable(),
19997
- agents: external_exports.array(machineAgentSchema),
19998
- /** The rules that fire for this machine; null or absent when healthy (older servers omit it). */
19999
- health: machineHealthViewSchema.nullable().optional()
20000
- });
20001
- var patchMachineBody = external_exports.object({
20002
- name: external_exports.string().trim().min(1).max(100).optional(),
20003
- project_ids: external_exports.array(idSchema).max(200).optional(),
20004
- default_project_id: idSchema.nullable().optional()
20005
- }).strict().refine((b) => b.name !== void 0 || b.project_ids !== void 0 || b.default_project_id !== void 0, "nothing to update");
20006
- var machineResponse = external_exports.object({ machine: machineSchema }).strict();
20007
- var CLI_MAJOR = 0;
20008
-
20009
- // ../shared/src/package-name.ts
20010
- var CLI_PACKAGE_NAME = "@hivefloor/cli";
20011
- var CLI_BIN_NAME = "hivefloor";
20012
- var CLI_INSTALL_COMMAND = `npm i -g ${CLI_PACKAGE_NAME}`;
20013
- function cliNpxCommand(args = "", opts = {}) {
20014
- const spec = opts.pinMajor ? `${CLI_PACKAGE_NAME}@${CLI_MAJOR}` : CLI_PACKAGE_NAME;
20015
- return `npx ${spec}${args ? ` ${args}` : ""}`;
20016
- }
20017
- var CLI_CONNECT_COMMAND = cliNpxCommand("connect");
20018
-
20019
- // ../shared/src/usage.ts
20020
- var MIN_SPAN_MS = 5 * 6e4;
20021
- var MAX_ETA_MS = 31 * 24 * 36e5;
20022
- var USAGE_COUNTERS = ["tokens_in", "tokens_out", "cost_usd"];
20023
- function isUsageCounter(value) {
20024
- return USAGE_COUNTERS.includes(value);
20025
- }
20026
- function parseUsageKey(key2) {
20027
- const parts = key2.split(":");
20028
- if (parts.length < 3) return null;
20029
- const tool = parts[0];
20030
- const profile = parts[1];
20031
- if (!TOOLS.includes(tool)) return null;
20032
- if (!PROFILE_KEY_RE.test(profile)) return null;
20033
- if (parts.length === 3) {
20034
- const counter2 = parts[2];
20035
- return isUsageCounter(counter2) ? { tool, profile, session: null, counter: counter2 } : null;
20036
- }
20037
- if (parts[2] !== "s" || parts.length < 5) return null;
20038
- const session = parts.slice(3, -1).join(":");
20039
- const counter = parts[parts.length - 1];
20040
- if (!session || !isUsageCounter(counter)) return null;
20041
- return { tool, profile, session, counter };
20042
- }
20043
-
20044
- // ../shared/src/usage-alerts.ts
20045
- var WASTE_WITHIN_MS = 3 * 36e5;
20046
-
20047
19926
  // ../shared/src/task-status.ts
20048
19927
  var TASK_STATUSES = ["backlog", "ready", "claimed", "in_review", "done", "blocked", "parked"];
20049
19928
  var taskStatusSchema = external_exports.enum(TASK_STATUSES);
20050
19929
 
20051
19930
  // ../shared/src/health.ts
19931
+ var STALLED_AFTER_SEC = 120;
20052
19932
  var PARKED_AFTER_SEC = 20 * 60;
20053
19933
  var WAITING_LONG_AFTER_SEC = 15 * 60;
20054
19934
  var MIN_STALL_THRESHOLD_SEC = 60;
@@ -20180,6 +20060,8 @@ var taskTimelineEventSchema = external_exports.object({
20180
20060
  avatar_url: external_exports.string().nullable()
20181
20061
  }),
20182
20062
  text: external_exports.string().nullable(),
20063
+ /** `answered` lines only: where the person sent the task with the answer (`ready`, `backlog`, `done` or `blocked`). */
20064
+ then: external_exports.enum(["ready", "backlog", "done", "blocked"]).optional(),
20183
20065
  created_at: isoTimeSchema
20184
20066
  });
20185
20067
  var taskListSchema = external_exports.object({
@@ -20229,7 +20111,7 @@ var answerBodySchema = external_exports.object({
20229
20111
  text: external_exports.string().trim().min(1).max(500),
20230
20112
  waiting_since: isoTimeSchema.optional()
20231
20113
  });
20232
- var NOTIFICATION_KINDS = ["task_done", "task_blocked", "agent_waiting", "invite_received", "member_added", "repo_link_requested", "agent_question", "feedback", "usage_waste", "usage_high", "wait_escalated", "machine_unhealthy"];
20114
+ var NOTIFICATION_KINDS = ["task_done", "task_blocked", "agent_waiting", "invite_received", "member_added", "repo_link_requested", "agent_question", "feedback", "usage_waste", "usage_high", "wait_escalated", "machine_unhealthy", "team_visibility"];
20233
20115
  var notificationKindSchema = external_exports.enum(NOTIFICATION_KINDS);
20234
20116
  var notificationViewSchema = external_exports.object({
20235
20117
  id: entityIdSchema,
@@ -20341,6 +20223,248 @@ var releaseBody = external_exports.object({
20341
20223
  }).strict();
20342
20224
  var completeBody = external_exports.object({ claim_token: claimToken.optional(), summary: external_exports.string().min(1).max(5e3), pr_url: external_exports.string().max(1e3).optional(), session: sessionRef.optional() }).strict();
20343
20225
 
20226
+ // ../shared/src/api/control.ts
20227
+ var CONTROL_KINDS = ["message", "approve", "deny", "stop", "resume", "peek"];
20228
+ var CONTROL_STATUSES = ["queued", "delivered", "done", "failed", "expired"];
20229
+ var CONTROL_VIAS = ["tmux", "hook", "adapter"];
20230
+ var CONTROL_TEXT_MAX = 4e3;
20231
+ var CONTROL_REASON_MAX = 300;
20232
+ var CONTROL_REPLY_MAX = 2048;
20233
+ var PEEK_LINES_MAX = 60;
20234
+ var PEEK_OUTPUT_MAX = 4096;
20235
+ function stripControlChars(input2) {
20236
+ return input2.normalize("NFC").replace(/\r\n?/g, "\n").replace(/[\u0000-\u0008\u000B-\u001F\u007F-\u009F]/g, "");
20237
+ }
20238
+ function cleanControlText(input2, max = CONTROL_TEXT_MAX) {
20239
+ const text2 = stripControlChars(input2);
20240
+ if (text2.length === 0) return null;
20241
+ if (text2.length > max && Array.from(text2).length > max) return null;
20242
+ return text2;
20243
+ }
20244
+ var cleaned = (max) => external_exports.string().transform((s, ctx) => {
20245
+ const t = cleanControlText(s, max);
20246
+ if (t === null) {
20247
+ ctx.addIssue({ code: "custom", message: `must be 1 to ${max} characters after cleaning` });
20248
+ return external_exports.NEVER;
20249
+ }
20250
+ return t;
20251
+ });
20252
+ var promptIdSchema = external_exports.string().regex(/^[A-Za-z0-9_-]{8,128}$/, "a prompt id");
20253
+ var idempotencyKeySchema = external_exports.string().min(8).max(64);
20254
+ var createCommandBody = external_exports.discriminatedUnion("kind", [
20255
+ external_exports.strictObject({ kind: external_exports.literal("message"), args: external_exports.strictObject({ text: cleaned(CONTROL_TEXT_MAX) }), idempotency_key: idempotencyKeySchema }),
20256
+ external_exports.strictObject({ kind: external_exports.literal("approve"), args: external_exports.strictObject({ prompt_id: promptIdSchema }), idempotency_key: idempotencyKeySchema }),
20257
+ external_exports.strictObject({
20258
+ kind: external_exports.literal("deny"),
20259
+ args: external_exports.strictObject({
20260
+ prompt_id: promptIdSchema,
20261
+ // a reason that cleans to nothing is no reason
20262
+ reason: external_exports.string().max(CONTROL_REASON_MAX).transform((s) => cleanControlText(s, CONTROL_REASON_MAX) ?? void 0).optional()
20263
+ }),
20264
+ idempotency_key: idempotencyKeySchema
20265
+ }),
20266
+ external_exports.strictObject({ kind: external_exports.literal("stop"), args: external_exports.strictObject({ mode: external_exports.enum(["interrupt", "end"]) }), idempotency_key: idempotencyKeySchema }),
20267
+ // No args: the machine runs a fixed command for the tool it recorded, in the folder it recorded.
20268
+ // `revive: true` brings back a session that Finished (o160 4): same command, same checks; the new instruction goes later as a message.
20269
+ external_exports.strictObject({ kind: external_exports.literal("resume"), args: external_exports.strictObject({}), revive: external_exports.boolean().optional(), idempotency_key: idempotencyKeySchema }),
20270
+ // Read-only: the last lines of the session's screen (or transcript), redacted on the machine.
20271
+ external_exports.strictObject({ kind: external_exports.literal("peek"), args: external_exports.strictObject({ lines: external_exports.number().int().min(1).max(PEEK_LINES_MAX) }), idempotency_key: idempotencyKeySchema })
20272
+ ]);
20273
+ var requestedBySchema = external_exports.object({ user_id: external_exports.string(), name: external_exports.string() });
20274
+ var commandEventSchema = external_exports.object({
20275
+ id: external_exports.string(),
20276
+ session_id: external_exports.string(),
20277
+ kind: external_exports.enum(CONTROL_KINDS),
20278
+ status: external_exports.enum(CONTROL_STATUSES),
20279
+ code: external_exports.string().optional(),
20280
+ via: external_exports.enum(CONTROL_VIAS).optional(),
20281
+ requested_by: requestedBySchema,
20282
+ created_at: isoTimeSchema,
20283
+ updated_at: isoTimeSchema
20284
+ });
20285
+ var commandSchema = commandEventSchema.extend({
20286
+ detail: external_exports.string().optional(),
20287
+ args: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
20288
+ output: external_exports.string().optional()
20289
+ });
20290
+ var commandResponse = external_exports.object({ command: commandSchema });
20291
+ var commandListResponse = external_exports.object({ commands: external_exports.array(commandSchema) });
20292
+ var commandUpdateEvent = external_exports.object({ command: commandEventSchema });
20293
+ var sessionPromptEvent = external_exports.union([
20294
+ external_exports.object({ session_id: external_exports.string(), prompt_id: external_exports.string(), tool_name: external_exports.string(), summary: external_exports.string(), expires_at: isoTimeSchema }),
20295
+ external_exports.object({ session_id: external_exports.string(), prompt_id: external_exports.string(), closed: external_exports.literal(true) })
20296
+ ]);
20297
+ var sessionReplyEvent = external_exports.object({ session_id: external_exports.string(), text: external_exports.string(), at: isoTimeSchema });
20298
+ var machineCommandSchema = external_exports.object({
20299
+ id: external_exports.string(),
20300
+ kind: external_exports.enum(CONTROL_KINDS),
20301
+ args: external_exports.record(external_exports.string(), external_exports.unknown()),
20302
+ session: external_exports.object({ external_id: external_exports.string(), tool: external_exports.string(), profile: external_exports.string().nullable() }),
20303
+ requested_by: requestedBySchema.extend({ is_machine_owner: external_exports.boolean() }),
20304
+ expires_in_ms: external_exports.number().int()
20305
+ });
20306
+ var machineCommandsResponse = external_exports.object({ commands: external_exports.array(machineCommandSchema) });
20307
+ var commandResultBody = external_exports.object({
20308
+ status: external_exports.enum(["done", "failed"]),
20309
+ code: external_exports.string().regex(/^[a-z][a-z0-9_]{0,39}$/).optional(),
20310
+ detail: external_exports.string().max(200).optional(),
20311
+ via: external_exports.enum(CONTROL_VIAS).optional(),
20312
+ /** A done `peek` only: the screen lines, redacted on the machine. The server ignores it for any other kind. */
20313
+ output: external_exports.string().max(PEEK_OUTPUT_MAX).optional()
20314
+ }).strict();
20315
+ var machinePromptBody = external_exports.object({
20316
+ session_id: external_exports.string().min(1).max(200),
20317
+ prompt_id: promptIdSchema,
20318
+ tool_name: external_exports.string().min(1).max(100),
20319
+ summary: external_exports.string().max(600)
20320
+ }).strict();
20321
+ var machinePromptResponse = external_exports.object({ hold: external_exports.boolean() });
20322
+ var controlVerbsSchema = external_exports.object({ message: external_exports.boolean().optional(), approve: external_exports.boolean().optional(), deny: external_exports.boolean().optional(), stop: external_exports.boolean().optional(), resume: external_exports.boolean().optional(), peek: external_exports.boolean().optional() }).strict();
20323
+
20324
+ // ../shared/src/api/machines.ts
20325
+ var MACHINE_HEARTBEAT_SECONDS = 30;
20326
+ var MACHINE_MIN_INTERVAL_SECONDS = 15;
20327
+ var MACHINE_MAX_AGENTS = 40;
20328
+ var PROFILE_KEY_RE = /^[a-z0-9][a-z0-9._-]{0,39}$/;
20329
+ var profileKeySchema = external_exports.string().regex(PROFILE_KEY_RE, "bad profile key");
20330
+ var pct = external_exports.number().min(0).max(100);
20331
+ var machineStatsSchema = external_exports.object({
20332
+ cpu_pct: pct.optional(),
20333
+ mem_pct: pct.optional(),
20334
+ disk_pct: pct.optional(),
20335
+ mem_total_mb: external_exports.number().int().min(0).max(1e8).optional(),
20336
+ load1: external_exports.number().min(0).max(1e5).optional(),
20337
+ gpu: external_exports.array(external_exports.object({ name: external_exports.string().max(100), util_pct: pct.optional(), mem_pct: pct.optional() }).strict()).max(8).optional(),
20338
+ usage: external_exports.record(external_exports.string().max(80), external_exports.number().finite()).refine((o) => Object.keys(o).length <= 64, "at most 64 usage values").optional()
20339
+ }).strict();
20340
+ var ENDED_SESSION_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/;
20341
+ var ENDED_SESSIONS_MAX = 100;
20342
+ var machineHeartbeatBody = external_exports.object({
20343
+ os: external_exports.string().trim().min(1).max(100).optional(),
20344
+ cli_version: external_exports.string().trim().min(1).max(50).optional(),
20345
+ stats: machineStatsSchema.optional(),
20346
+ /** The control verbs switched on in `control.json` (docs/CONTROL.md 3.1). Absent: the server keeps what it has. */
20347
+ control: controlVerbsSchema.optional(),
20348
+ /** Tool session ids (the hook's `session_id`) whose agent process is gone on this machine: the server ends them. */
20349
+ ended_sessions: external_exports.array(external_exports.string().min(1).max(200).regex(ENDED_SESSION_ID_RE, "bad session id")).max(ENDED_SESSIONS_MAX).optional()
20350
+ }).strict();
20351
+ var projectBriefSchema2 = external_exports.object({ id: external_exports.string(), key: external_exports.string(), name: external_exports.string() });
20352
+ var machineHeartbeatResponseSchema = external_exports.object({
20353
+ ok: external_exports.literal(true),
20354
+ machine: external_exports.object({ id: external_exports.string(), name: external_exports.string() }),
20355
+ projects: external_exports.array(projectBriefSchema2),
20356
+ /** Seconds the service should wait before the next heartbeat. */
20357
+ interval: external_exports.number().int().positive()
20358
+ });
20359
+ var discoveryProfileSchema = external_exports.object({
20360
+ tool: toolSchema,
20361
+ key: profileKeySchema,
20362
+ /** For example `Claude Max (work)`; no email, no token. */
20363
+ label: external_exports.string().trim().max(100).optional(),
20364
+ model: external_exports.string().trim().max(200).optional(),
20365
+ running: external_exports.number().int().min(0).max(500)
20366
+ }).strict();
20367
+ var discoveryBody = external_exports.object({ profiles: external_exports.array(discoveryProfileSchema).max(MACHINE_MAX_AGENTS) }).strict();
20368
+ var SESSION_ACCOUNT_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,59}$/;
20369
+ var machineHookEventSchema = hookEventSchema.extend({
20370
+ profile: profileKeySchema.optional(),
20371
+ account: external_exports.string().regex(SESSION_ACCOUNT_RE).optional().catch(void 0)
20372
+ });
20373
+ var machineHookBatchSchema = external_exports.object({ events: external_exports.array(machineHookEventSchema).min(1).max(HOOK_BATCH_MAX) });
20374
+ var approveMachineBody = external_exports.object({
20375
+ name: external_exports.string().trim().min(1).max(100),
20376
+ project_ids: external_exports.array(idSchema).max(200).optional(),
20377
+ default_project_id: idSchema.nullable().optional(),
20378
+ /** Replace one of the person's own machines (listed in the preview's `reusable_machines`): its token is rotated, nothing else changes. */
20379
+ machine_id: idSchema.optional()
20380
+ }).strict();
20381
+ var machineTokenSuccessSchema = external_exports.object({
20382
+ token: external_exports.string().min(1),
20383
+ machine: external_exports.object({ id: external_exports.string(), name: external_exports.string() }),
20384
+ projects: external_exports.array(projectBriefSchema2)
20385
+ });
20386
+ var machineAgentSchema = external_exports.object({
20387
+ id: external_exports.string(),
20388
+ name: external_exports.string(),
20389
+ tool: toolSchema,
20390
+ profile: external_exports.string().nullable(),
20391
+ account_label: external_exports.string().nullable(),
20392
+ model: external_exports.string().nullable(),
20393
+ /** Agent processes alive at the last discovery. */
20394
+ running: external_exports.number().int().nonnegative(),
20395
+ /** Main sessions running now (live, waiting, idle, stalled): not offline or ended. */
20396
+ live_sessions: external_exports.number().int().nonnegative(),
20397
+ /** Of those, waiting on you (`needsYou`). Older servers omit it. */
20398
+ waiting_sessions: external_exports.number().int().nonnegative().optional(),
20399
+ /** Of those, idle (done, asked nothing). Older servers omit it. */
20400
+ idle_sessions: external_exports.number().int().nonnegative().optional(),
20401
+ last_seen_at: external_exports.string().nullable()
20402
+ });
20403
+ var machineHealthViewSchema = external_exports.object({
20404
+ level: external_exports.enum(["warn", "critical"]),
20405
+ findings: external_exports.array(external_exports.object({ rule: external_exports.enum(MACHINE_HEALTH_RULES), level: external_exports.enum(["warn", "critical"]), text: external_exports.string() }))
20406
+ });
20407
+ var machineSchema = external_exports.object({
20408
+ id: external_exports.string(),
20409
+ name: external_exports.string(),
20410
+ os: external_exports.string().nullable(),
20411
+ cli_version: external_exports.string().nullable(),
20412
+ online: external_exports.boolean(),
20413
+ last_seen_at: external_exports.string().nullable(),
20414
+ created_at: external_exports.string(),
20415
+ default_project_id: external_exports.string().nullable(),
20416
+ projects: external_exports.array(external_exports.object({ id: external_exports.string(), key: external_exports.string(), name: external_exports.string(), default: external_exports.boolean() })),
20417
+ stats: machineStatsSchema.nullable(),
20418
+ agents: external_exports.array(machineAgentSchema),
20419
+ /** The rules that fire for this machine; null or absent when healthy (older servers omit it). */
20420
+ health: machineHealthViewSchema.nullable().optional()
20421
+ });
20422
+ var patchMachineBody = external_exports.object({
20423
+ name: external_exports.string().trim().min(1).max(100).optional(),
20424
+ project_ids: external_exports.array(idSchema).max(200).optional(),
20425
+ default_project_id: idSchema.nullable().optional()
20426
+ }).strict().refine((b) => b.name !== void 0 || b.project_ids !== void 0 || b.default_project_id !== void 0, "nothing to update");
20427
+ var machineResponse = external_exports.object({ machine: machineSchema }).strict();
20428
+ var CLI_MAJOR = 0;
20429
+
20430
+ // ../shared/src/package-name.ts
20431
+ var CLI_PACKAGE_NAME = "@hivefloor/cli";
20432
+ var CLI_BIN_NAME = "hivefloor";
20433
+ var CLI_INSTALL_COMMAND = `npm i -g ${CLI_PACKAGE_NAME}`;
20434
+ function cliNpxCommand(args = "", opts = {}) {
20435
+ const spec = opts.pinMajor ? `${CLI_PACKAGE_NAME}@${CLI_MAJOR}` : CLI_PACKAGE_NAME;
20436
+ return `npx ${spec}${args ? ` ${args}` : ""}`;
20437
+ }
20438
+ var CLI_CONNECT_COMMAND = cliNpxCommand("connect");
20439
+
20440
+ // ../shared/src/usage.ts
20441
+ var MIN_SPAN_MS = 5 * 6e4;
20442
+ var MAX_ETA_MS = 31 * 24 * 36e5;
20443
+ var USAGE_COUNTERS = ["tokens_in", "tokens_out", "cost_usd"];
20444
+ function isUsageCounter(value) {
20445
+ return USAGE_COUNTERS.includes(value);
20446
+ }
20447
+ function parseUsageKey(key2) {
20448
+ const parts = key2.split(":");
20449
+ if (parts.length < 3) return null;
20450
+ const tool = parts[0];
20451
+ const profile = parts[1];
20452
+ if (!TOOLS.includes(tool)) return null;
20453
+ if (!PROFILE_KEY_RE.test(profile)) return null;
20454
+ if (parts.length === 3) {
20455
+ const counter2 = parts[2];
20456
+ return isUsageCounter(counter2) ? { tool, profile, session: null, counter: counter2 } : null;
20457
+ }
20458
+ if (parts[2] !== "s" || parts.length < 5) return null;
20459
+ const session = parts.slice(3, -1).join(":");
20460
+ const counter = parts[parts.length - 1];
20461
+ if (!session || !isUsageCounter(counter)) return null;
20462
+ return { tool, profile, session, counter };
20463
+ }
20464
+
20465
+ // ../shared/src/usage-alerts.ts
20466
+ var WASTE_WITHIN_MS = 3 * 36e5;
20467
+
20344
20468
  // ../shared/src/api/usage.ts
20345
20469
  var isoTime = external_exports.iso.datetime({ offset: true });
20346
20470
  var USAGE_PROVIDERS = [
@@ -20412,6 +20536,8 @@ var usageAccountViewSchema = external_exports.object({
20412
20536
  machines: external_exports.array(external_exports.string().max(80)).max(50),
20413
20537
  windows: external_exports.array(usageWindowViewSchema).max(20),
20414
20538
  issues: external_exports.array(usageIssueSchema).max(10).optional(),
20539
+ /** Distinct live agent lanes, independent of session/subagent count. */
20540
+ live_lanes: external_exports.number().int().nonnegative().optional(),
20415
20541
  /** How many live sessions draw on this account (subagents included). */
20416
20542
  live_sessions: external_exports.number().int().nonnegative().optional(),
20417
20543
  /** The live agents that draw on it, most recent first; `working` when one of its sessions works now. */
@@ -20437,6 +20563,8 @@ var projectUsageViewSchema = external_exports.object({
20437
20563
  id: entityIdSchema,
20438
20564
  key: external_exports.string(),
20439
20565
  name: external_exports.string(),
20566
+ /** The person's catch-all project: shown as "Unmapped sessions". */
20567
+ personal: external_exports.boolean().optional(),
20440
20568
  seconds: external_exports.number().int().nonnegative(),
20441
20569
  tokens_in: external_exports.number().int().nonnegative(),
20442
20570
  tokens_out: external_exports.number().int().nonnegative(),
@@ -20621,6 +20749,61 @@ function formatRemote(r) {
20621
20749
  return `${r.host}/${r.owner}/${r.name}`;
20622
20750
  }
20623
20751
 
20752
+ // ../shared/src/project-map.ts
20753
+ var CWD_PREFIX_MAX = 500;
20754
+ function normalizeCwdPrefix(input2) {
20755
+ let s = input2.replace(/[\u0000-\u001f\u007f]/g, "").trim().replace(/\\/g, "/");
20756
+ if (s === "" || s.length > CWD_PREFIX_MAX) return null;
20757
+ const drive = /^[A-Za-z]:(\/|$)/.test(s);
20758
+ if (!drive && !s.startsWith("/")) return null;
20759
+ const parts = s.split("/").filter((p) => p !== "" && p !== ".");
20760
+ if (parts.some((p) => p === "..")) return null;
20761
+ if (drive) {
20762
+ s = parts[0].toUpperCase() + (parts.length > 1 ? "/" + parts.slice(1).join("/") : "/");
20763
+ return parts.length > 1 ? s : null;
20764
+ }
20765
+ return parts.length === 0 ? null : "/" + parts.join("/");
20766
+ }
20767
+
20768
+ // ../shared/src/api/project-map.ts
20769
+ var cwdMapBody = external_exports.object({
20770
+ prefix: external_exports.string().max(CWD_PREFIX_MAX * 2).transform((s, ctx) => {
20771
+ const n = normalizeCwdPrefix(s);
20772
+ if (!n) ctx.addIssue({ code: "custom", message: "must be an absolute folder, for example /home/me/code/app" });
20773
+ return n ?? "";
20774
+ })
20775
+ }).strict();
20776
+ var cwdMapSchema = external_exports.object({ id: idSchema, project_id: idSchema, prefix: external_exports.string(), sessions: external_exports.number().int().nonnegative() }).strict();
20777
+ var seenRemoteSchema = external_exports.object({
20778
+ remote_key: external_exports.string(),
20779
+ sessions: external_exports.number().int().nonnegative(),
20780
+ /** Sessions of this remote still in the catch-all project. */
20781
+ unmapped: external_exports.number().int().nonnegative(),
20782
+ last_seen: external_exports.string().nullable(),
20783
+ /** Projects the remote is linked to (active links). Several is ambiguous: its sessions are routed by folder. */
20784
+ project_ids: external_exports.array(idSchema),
20785
+ /** A project the person may link it to, taken from where its sessions already ran or from a folder entry; null when unknown. */
20786
+ suggested_project_id: idSchema.nullable()
20787
+ }).strict();
20788
+ var mapProjectSchema = external_exports.object({
20789
+ id: idSchema,
20790
+ key: external_exports.string(),
20791
+ name: external_exports.string(),
20792
+ /** The catch-all: shown as "Unmapped sessions", never a target of a link. */
20793
+ personal: external_exports.boolean(),
20794
+ role: external_exports.enum(["owner", "admin", "member", "viewer"]),
20795
+ sessions: external_exports.number().int().nonnegative()
20796
+ }).strict();
20797
+ var projectMapResponse = external_exports.object({
20798
+ projects: external_exports.array(mapProjectSchema),
20799
+ remotes: external_exports.array(seenRemoteSchema),
20800
+ cwd_maps: external_exports.array(cwdMapSchema),
20801
+ total_sessions: external_exports.number().int().nonnegative(),
20802
+ unmapped_sessions: external_exports.number().int().nonnegative()
20803
+ }).strict();
20804
+ var projectMapApplyResponse = external_exports.object({ moved: external_exports.number().int().nonnegative(), kept: external_exports.number().int().nonnegative() }).strict();
20805
+ var cwdMapResponse = external_exports.object({ cwd_map: cwdMapSchema, moved: external_exports.number().int().nonnegative() }).strict();
20806
+
20624
20807
  // ../shared/src/redact.ts
20625
20808
  var tag = (kind) => `[redacted:${kind}]`;
20626
20809
  function isPlaceholder(value) {
@@ -20687,6 +20870,31 @@ function redact(input2) {
20687
20870
  return { text: text2, count };
20688
20871
  }
20689
20872
 
20873
+ // ../shared/src/session-end.ts
20874
+ var SESSION_END_KINDS = ["finished", "interrupted", "unknown"];
20875
+ var SESSION_END_REASONS = [
20876
+ /** Finished: the tool's SessionEnd hook came after the turn ended (the person quit it, `/clear`, a one-shot run that exited). */
20877
+ "exited",
20878
+ /** Finished: the process went away after its last turn ended. */
20879
+ "closed_after_turn",
20880
+ /** Interrupted: the tool quit (SessionEnd) while a turn was open. */
20881
+ "quit_mid_turn",
20882
+ /** Interrupted: the process went away mid-turn (terminal closed, crash, killed). */
20883
+ "process_gone",
20884
+ /** Interrupted: the session went silent until the offline lease ran out while its machine stopped reporting (slept, rebooted, offline). */
20885
+ "machine_offline",
20886
+ /** Interrupted: the session went silent until the offline lease ran out while its machine still reported (the process died). */
20887
+ "process_lost",
20888
+ /** Unknown: the agent was disconnected or removed. */
20889
+ "agent_removed",
20890
+ /** Unknown: the machine lost access to the project. */
20891
+ "access_revoked",
20892
+ /** Unknown: a fleet lane reported stopped. */
20893
+ "fleet_stopped",
20894
+ /** Unknown: nothing tells how the last turn went. */
20895
+ "no_signal"
20896
+ ];
20897
+
20690
20898
  // ../shared/src/api/nudge.ts
20691
20899
  var NUDGE_TTL_SEC = 24 * 3600;
20692
20900
  var NUDGE_NOTE_MAX = 300;
@@ -20774,7 +20982,9 @@ var floorAgentSchema = external_exports.object({
20774
20982
  machine: external_exports.string().nullable(),
20775
20983
  default_model: external_exports.string().nullable(),
20776
20984
  owner_id: entityIdSchema,
20777
- last_seen_at: isoTimeSchema.nullable()
20985
+ last_seen_at: isoTimeSchema.nullable(),
20986
+ /** The agent's machine's last heartbeat (null: no live machine). The browser treats the machine as online within `MACHINE_ONLINE_SECONDS` of it; Resume needs that. Never in a share link. Older servers omit it. */
20987
+ machine_seen_at: isoTimeSchema.nullable().optional()
20778
20988
  });
20779
20989
  var floorSessionSchema = external_exports.object({
20780
20990
  id: entityIdSchema,
@@ -20808,6 +21018,12 @@ var floorSessionSchema = external_exports.object({
20808
21018
  started_at: isoTimeSchema,
20809
21019
  last_event_at: isoTimeSchema,
20810
21020
  ended_at: isoTimeSchema.nullable(),
21021
+ /** How an ended main session ended (o147): Resume is offered only for 'interrupted'. Null while live; older servers omit it. */
21022
+ end_kind: external_exports.enum(SESSION_END_KINDS).nullable().optional(),
21023
+ /** The stored reason (`SESSION_END_REASON_TEXT` has it in plain words). */
21024
+ end_reason: external_exports.enum(SESSION_END_REASONS).nullable().optional(),
21025
+ /** Set while a session revived after it Finished (o160 4) runs; cleared on its next end. Older servers omit it. */
21026
+ revived_at: isoTimeSchema.nullable().optional(),
20811
21027
  /** Latest nudge from the last day, or null. Older servers omit it. */
20812
21028
  nudge: sessionNudgeAckSchema.nullable().optional(),
20813
21029
  get children() {
@@ -20830,14 +21046,25 @@ var floorSnapshotSchema = external_exports.object({
20830
21046
  }),
20831
21047
  pods: external_exports.array(floorPodSchema),
20832
21048
  shelves: external_exports.object({
20833
- /** Every ready task, most urgent first (at most 200). */
21049
+ /** Ready tasks, most urgent first (at most 200). */
20834
21050
  ready: external_exports.array(taskCardSchema),
21051
+ /** In review, newest first (at most 200). */
20835
21052
  in_review: external_exports.array(taskCardSchema),
20836
21053
  /** Done in the last 24 hours, newest first (at most 50). The client keeps those done since its local midnight. */
20837
21054
  done_today: external_exports.array(taskCardSchema)
20838
21055
  }),
20839
- /** Claimed and blocked tasks, shown on their holder's tile (`session.task_id`). */
21056
+ /** Claimed and blocked tasks, shown on their holder's tile (`session.task_id`). Each status is at most 200. */
20840
21057
  claimed: external_exports.array(taskCardSchema),
21058
+ /**
21059
+ * Set when a shelf was cut at 200. A number is how many rows were left off, when the server counted them;
21060
+ * `true` means there is at least one more. A shelf that fit is omitted, and so is this object when every shelf fit.
21061
+ */
21062
+ truncated: external_exports.object({
21063
+ ready: external_exports.union([external_exports.literal(true), external_exports.number().int().positive()]).optional(),
21064
+ in_review: external_exports.union([external_exports.literal(true), external_exports.number().int().positive()]).optional(),
21065
+ claimed: external_exports.union([external_exports.literal(true), external_exports.number().int().positive()]).optional(),
21066
+ blocked: external_exports.union([external_exports.literal(true), external_exports.number().int().positive()]).optional()
21067
+ }).optional(),
20841
21068
  /** The id of the newest event the snapshot includes; the client ignores stream events up to it. Null when there is none. */
20842
21069
  last_event_id: entityIdSchema.nullable(),
20843
21070
  server_time: isoTimeSchema
@@ -20845,7 +21072,14 @@ var floorSnapshotSchema = external_exports.object({
20845
21072
  var floorStreamPayloads = {
20846
21073
  /** A session upsert; `agent` and `user` let the client place a session of an agent it has not seen yet. */
20847
21074
  session: external_exports.object({ session: floorSessionSchema, agent: floorAgentSchema, user: floorUserSchema }),
20848
- session_end: external_exports.object({ session_id: entityIdSchema, agent_id: entityIdSchema, ended_at: isoTimeSchema }),
21075
+ session_end: external_exports.object({
21076
+ session_id: entityIdSchema,
21077
+ agent_id: entityIdSchema,
21078
+ ended_at: isoTimeSchema,
21079
+ /** How it ended (o147); older servers omit it. */
21080
+ end_kind: external_exports.enum(SESSION_END_KINDS).nullable().optional(),
21081
+ end_reason: external_exports.enum(SESSION_END_REASONS).nullable().optional()
21082
+ }),
20849
21083
  task: external_exports.object({ task: taskCardSchema }),
20850
21084
  task_event: external_exports.object({ event: taskTimelineEventSchema }),
20851
21085
  notification: external_exports.object({ notification: notificationViewSchema }),
@@ -20991,13 +21225,27 @@ var HOUR_MS = 36e5;
20991
21225
  var MAX_FLOOR_RANGE_MS = 8 * 24 * HOUR_MS;
20992
21226
  var DEFAULT_FLOOR_WINDOW_MS = 24 * HOUR_MS;
20993
21227
 
21228
+ // ../shared/src/session-state.ts
21229
+ var OFFLINE_AFTER_SEC = 300;
21230
+ var OFFLINE_LEASE_SEC = 6 * 3600;
21231
+ var ENDED_LISTED_SEC = 24 * 3600;
21232
+ var DISPLAY_STATE_LEGEND = {
21233
+ live: { label: "Live", text: "Working now: a turn is running." },
21234
+ waiting: { label: "Waiting on you", text: 'Asked a question or wants a permission. Only these count in "need you".' },
21235
+ idle: { label: "Idle (done)", text: 'Finished its turn with a report and asked nothing. Never counts in "need you".' },
21236
+ stalled: { label: "Stalled", text: `Working, but nothing heard for ${STALLED_AFTER_SEC / 60} min or more.` },
21237
+ offline: { label: "Offline", text: `No heartbeat for ${OFFLINE_AFTER_SEC / 60} min, the machine is off or the process is gone. Moves to Ended after ${OFFLINE_LEASE_SEC / 3600} h.` },
21238
+ ended: { label: "Ended", text: `Closed, or offline past its lease. Listed under "Ended (n)" for ${ENDED_LISTED_SEC / 3600} h; never counted as an agent.` }
21239
+ };
21240
+
20994
21241
  // ../shared/src/client-routes.ts
20995
21242
  var SEGMENT = "[^/]+";
20996
21243
  var PROJECT_TABS = "(?:board|done|team|memory|agents|settings|welcome)";
20997
21244
  var CLIENT_ROUTE_PATTERNS = [
20998
21245
  /^\/$/,
20999
- /^\/(?:about|docs|signin|signup|app|connect|floor|hive|floor3d|machines|new|settings|inbox|feedback|usage|demo)$/,
21000
- new RegExp(`^/(?:s|invite)/${SEGMENT}$`),
21246
+ /^\/docs\/quest$/,
21247
+ /^\/(?:about|docs|signin|signup|app|connect|floor|hive|floor3d|machines|new|settings|inbox|needs-you|feedback|usage|demo|orchestrator|voice-lab)$/,
21248
+ new RegExp(`^/(?:s|invite|u)/${SEGMENT}$`),
21001
21249
  new RegExp(`^/p/${SEGMENT}$`),
21002
21250
  new RegExp(`^/p/${SEGMENT}/${PROJECT_TABS}$`),
21003
21251
  new RegExp(`^/p/${SEGMENT}/board/${SEGMENT}$`)
@@ -21082,9 +21330,9 @@ function claudeModelPrice(model) {
21082
21330
  const m = model.toLowerCase();
21083
21331
  const at = m.indexOf("claude-");
21084
21332
  if (at < 0) return null;
21085
- const id = m.slice(at);
21333
+ const id2 = m.slice(at);
21086
21334
  for (const [prefix, price] of CLAUDE_PRICES) {
21087
- if (id === prefix || id.startsWith(`${prefix}-`) || id.startsWith(`${prefix}[`) || id.startsWith(`${prefix}@`) || id.startsWith(`${prefix}:`)) return price;
21335
+ if (id2 === prefix || id2.startsWith(`${prefix}-`) || id2.startsWith(`${prefix}[`) || id2.startsWith(`${prefix}@`) || id2.startsWith(`${prefix}:`)) return price;
21088
21336
  }
21089
21337
  return null;
21090
21338
  }
@@ -21099,6 +21347,8 @@ function estimateClaudeCostUsd(model, t) {
21099
21347
  // ../shared/src/api/inbox.ts
21100
21348
  var INBOX_KINDS = ["blocked_task", "waiting", "question"];
21101
21349
  var inboxKindSchema = external_exports.enum(INBOX_KINDS);
21350
+ var LISTENERS = ["agent", "fleet", "none"];
21351
+ var listenerSchema = external_exports.enum(LISTENERS);
21102
21352
  var inboxItemSchema = external_exports.object({
21103
21353
  /** `task:<id>`, `session:<id>` or `question:<id>`. */
21104
21354
  id: external_exports.string().regex(/^(task|session|question):\d{1,20}$/),
@@ -21109,6 +21359,16 @@ var inboxItemSchema = external_exports.object({
21109
21359
  /** The question or status text (redacted, at most 1000 characters). */
21110
21360
  text: external_exports.string(),
21111
21361
  waiting_since: isoTimeSchema,
21362
+ /**
21363
+ * Whether an agent or session is on the item. A blocked task nobody holds (a backlog import, a released claim) has no one to
21364
+ * read the answer: the answer is saved on the task only. Sessions and questions always have an agent. Absent from older servers: treat as true.
21365
+ */
21366
+ has_holder: external_exports.boolean().optional(),
21367
+ /**
21368
+ * Who acts on the answer: a live `agent` session, the `fleet` (an imported task: the fleet lead reads `answered` events through the
21369
+ * bridge) or `none` (nobody: the answer is only saved). Absent from older servers.
21370
+ */
21371
+ listener: listenerSchema.optional(),
21112
21372
  /** Whether the caller may answer it (role, the project's answer setting, and for a member: owning the agent). */
21113
21373
  can_answer: external_exports.boolean(),
21114
21374
  /** Whether the caller may nudge the item's session now (F2): owner or admin, and the session is stalled, parked, waiting too long or looping. */
@@ -21136,6 +21396,8 @@ var inboxListSchema = external_exports.object({
21136
21396
  /** Present (true) when a kind had more rows than this response loaded. The list loads 200 per kind, and a `cursor` past that loads further, up to 1000. `total` and `groups` then cover the loaded rows, while `count` stays exact. */
21137
21397
  truncated: external_exports.boolean().optional()
21138
21398
  });
21399
+ var ANSWER_THEN = ["ready", "backlog", "done", "blocked"];
21400
+ var answerThenSchema = external_exports.enum(ANSWER_THEN);
21139
21401
  var inboxAnswerBodySchema = external_exports.object({
21140
21402
  text: external_exports.string().trim().min(1).max(4e3),
21141
21403
  /**
@@ -21143,8 +21405,28 @@ var inboxAnswerBodySchema = external_exports.object({
21143
21405
  * answer to a wait that changed in the meantime (409 `not_waiting`): the answer would approve a prompt the
21144
21406
  * person never read.
21145
21407
  */
21146
- waiting_since: isoTimeSchema.optional()
21408
+ waiting_since: isoTimeSchema.optional(),
21409
+ /** Blocked-task items only: the status the task takes after the answer (default `ready`). Sessions and questions refuse anything but `ready` (400). */
21410
+ then: answerThenSchema.optional()
21147
21411
  }).strict();
21412
+ var inboxAnswerResponseSchema = external_exports.object({ ok: external_exports.literal(true), count: external_exports.number().int().min(0), listener: listenerSchema });
21413
+ var DELIVERY_STATES = ["waiting", "delivered", "acknowledged", "no_listener"];
21414
+ var deliveryStateSchema = external_exports.enum(DELIVERY_STATES);
21415
+ var inboxAnsweredItemSchema = external_exports.object({
21416
+ id: external_exports.string().regex(/^(task|session|question):\d{1,20}$/),
21417
+ kind: inboxKindSchema,
21418
+ project: external_exports.object({ id: entityIdSchema, key: external_exports.string(), name: external_exports.string() }),
21419
+ task: external_exports.object({ id: entityIdSchema, num: external_exports.number().int().positive(), key: external_exports.string(), title: external_exports.string() }).nullable(),
21420
+ text: external_exports.string(),
21421
+ answer: external_exports.string(),
21422
+ answered_at: isoTimeSchema,
21423
+ listener: listenerSchema,
21424
+ delivery: deliveryStateSchema,
21425
+ delivered_at: isoTimeSchema.nullable(),
21426
+ /** A task answer's outcome (`ready`, `backlog`, `done` or `blocked`). */
21427
+ then: answerThenSchema.nullable()
21428
+ });
21429
+ var inboxAnsweredListSchema = external_exports.object({ items: external_exports.array(inboxAnsweredItemSchema) });
21148
21430
  var askBody = external_exports.object({
21149
21431
  question: external_exports.string().trim().min(1).max(1e3),
21150
21432
  project: external_exports.union([external_exports.string().trim().min(1).max(100), external_exports.number().int().positive()]).transform(String).optional(),
@@ -21158,7 +21440,8 @@ var questionViewSchema = external_exports.object({
21158
21440
  session_id: entityIdSchema.nullable(),
21159
21441
  question: external_exports.string(),
21160
21442
  answer: external_exports.string().nullable(),
21161
- status: external_exports.enum(["open", "answered"]),
21443
+ /** `closed`: nobody answered it and it no longer waits (it expired, its session ended or its task was closed). */
21444
+ status: external_exports.enum(["open", "answered", "closed"]),
21162
21445
  asked_at: isoTimeSchema,
21163
21446
  answered_at: isoTimeSchema.nullable(),
21164
21447
  read_at: isoTimeSchema.nullable()
@@ -21212,6 +21495,52 @@ var teamViewSchema = external_exports.object({
21212
21495
  next_cursor: external_exports.string().nullable().optional()
21213
21496
  }).strict();
21214
21497
 
21498
+ // ../shared/src/api/team-visibility.ts
21499
+ var VISIBILITY_LEVELS = ["none", "counts", "live"];
21500
+ var visibilityLevelSchema = external_exports.enum(VISIBILITY_LEVELS);
21501
+ var roleEnum2 = external_exports.enum(["owner", "admin", "member", "viewer"]);
21502
+ var teamVisibilityPolicySchema = external_exports.object({
21503
+ member_visibility: visibilityLevelSchema,
21504
+ outside_counts: external_exports.boolean(),
21505
+ allow_member_listing: external_exports.boolean()
21506
+ }).strict();
21507
+ var putTeamVisibilityBody = teamVisibilityPolicySchema.partial().strict().refine((b) => b.member_visibility !== void 0 || b.outside_counts !== void 0 || b.allow_member_listing !== void 0, "nothing to update");
21508
+ var shareLevelBody = external_exports.object({ share_level: visibilityLevelSchema }).strict();
21509
+ var shareLevelResponse = external_exports.object({
21510
+ share_level: visibilityLevelSchema,
21511
+ cap: visibilityLevelSchema,
21512
+ effective: visibilityLevelSchema
21513
+ }).strict();
21514
+ var heatmapSchema = external_exports.object({
21515
+ metric: external_exports.literal("sessions"),
21516
+ days: external_exports.array(external_exports.object({ day: external_exports.string(), value: external_exports.number() }).strict())
21517
+ }).strict();
21518
+ var rosterTotalsSchema = external_exports.object({
21519
+ sessions_started: external_exports.number().int().nonnegative(),
21520
+ sessions_finished: external_exports.number().int().nonnegative(),
21521
+ agent_hours: external_exports.number().nonnegative(),
21522
+ machines: external_exports.number().int().nonnegative(),
21523
+ longest_streak: external_exports.number().int().nonnegative(),
21524
+ current_streak: external_exports.number().int().nonnegative()
21525
+ }).strict();
21526
+ var liveCountsSchema = external_exports.object({
21527
+ agents: external_exports.number().int().nonnegative(),
21528
+ machines: external_exports.number().int().nonnegative()
21529
+ }).strict();
21530
+ var rosterEntrySchema = external_exports.object({
21531
+ user: external_exports.object({ id: idSchema, login: external_exports.string(), avatar_url: external_exports.string().nullable() }).strict(),
21532
+ role: roleEnum2,
21533
+ heatmap: heatmapSchema.optional(),
21534
+ totals: rosterTotalsSchema.optional(),
21535
+ live: liveCountsSchema.optional()
21536
+ }).strict();
21537
+ var teamActivityResponse = external_exports.object({
21538
+ policy: teamVisibilityPolicySchema,
21539
+ you: external_exports.object({ share_level: visibilityLevelSchema, cap: visibilityLevelSchema, effective: visibilityLevelSchema }).strict(),
21540
+ heatmap: heatmapSchema,
21541
+ members: external_exports.array(rosterEntrySchema)
21542
+ }).strict();
21543
+
21215
21544
  // ../shared/src/api/fleet.ts
21216
21545
  var FLEET_STATES = ["working", "idle", "waiting", "paused", "stopped", "unknown"];
21217
21546
  var fleetStateSchema = external_exports.enum(FLEET_STATES);
@@ -21364,6 +21693,81 @@ var URL_OR_PATH_RE = new RegExp(
21364
21693
  "g"
21365
21694
  );
21366
21695
 
21696
+ // ../shared/src/api/audit.ts
21697
+ var auditEntrySchema = external_exports.object({
21698
+ id: idSchema,
21699
+ /** The project the action was on; null for a user-level action (a token issued, a machine removed). */
21700
+ project_id: idSchema.nullable(),
21701
+ user_id: idSchema.nullable(),
21702
+ user_login: external_exports.string().nullable(),
21703
+ agent_id: idSchema.nullable(),
21704
+ action: external_exports.string().min(1).max(100),
21705
+ /** Small JSON detail written with the action. Never holds a token or secret. */
21706
+ data: external_exports.record(external_exports.string(), external_exports.unknown()),
21707
+ at: isoTimeSchema
21708
+ }).strict();
21709
+ var auditListResponse = external_exports.object({
21710
+ items: external_exports.array(auditEntrySchema),
21711
+ /** Pass as `cursor` for the next (older) page; null on the last page. */
21712
+ next_cursor: external_exports.string().nullable()
21713
+ }).strict();
21714
+
21715
+ // ../shared/src/orch-schedules.ts
21716
+ var MIN_GAP_MINUTES = 5;
21717
+ function cronFields(cron) {
21718
+ const parts = cron.trim().split(/\s+/);
21719
+ if (parts.length !== 5) throw new Error("Use five cron fields: minute hour day month weekday.");
21720
+ return parts.map((raw, i) => {
21721
+ const names = i === 3 ? ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"] : i === 4 ? ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"] : [];
21722
+ const part = raw.toUpperCase().replace(/[A-Z]+/g, (name) => {
21723
+ const n = names.indexOf(name);
21724
+ return n < 0 ? name : String(n + (i === 3 ? 1 : 0));
21725
+ });
21726
+ const [min, max] = [[0, 59], [0, 23], [1, 31], [1, 12], [0, 7]][i];
21727
+ const values = /* @__PURE__ */ new Set();
21728
+ for (const item of part.split(",")) {
21729
+ const match = /^(\*|\d+(?:-\d+)?)(?:\/(\d+))?$/.exec(item);
21730
+ if (!match) throw new Error("Invalid cron field.");
21731
+ const step = Number(match[2] ?? 1);
21732
+ const range = match[1];
21733
+ const [start, end] = range === "*" ? [min, max] : range.includes("-") ? range.split("-").map(Number) : [Number(range), match[2] ? max : Number(range)];
21734
+ if (step < 1 || start < min || end > max || start > end) throw new Error("Cron value is out of range.");
21735
+ for (let v = start; v <= end; v += step) values.add(i === 4 && v === 7 ? 0 : v);
21736
+ }
21737
+ return { values: [...values].sort((a, b) => a - b), wildcard: part === "*" };
21738
+ });
21739
+ }
21740
+ function formatter(tz) {
21741
+ return new Intl.DateTimeFormat("en-CA", { timeZone: tz, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", hourCycle: "h23" });
21742
+ }
21743
+ function scheduleError(s) {
21744
+ if (!s.sessionTarget.trim()) return "Choose a session target.";
21745
+ if (!s.prompt.trim()) return "Enter a prompt.";
21746
+ try {
21747
+ formatter(s.tz).format(0);
21748
+ } catch {
21749
+ return "Enter a valid IANA time zone.";
21750
+ }
21751
+ if (Number(s.at !== void 0) + Number(s.every !== void 0) !== 1) return "Choose one time or one repeat rule.";
21752
+ if (s.at !== void 0) {
21753
+ const match = /^(\d{4})-(\d{2})-(\d{2})T([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d)(?:\.\d{1,3})?)?(?:Z|[+-]\d{2}:\d{2})$/i.exec(s.at);
21754
+ const calendar = match ? new Date(Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3]))) : null;
21755
+ return match && Number.isFinite(Date.parse(s.at)) && calendar?.getUTCMonth() === Number(match[2]) - 1 && calendar.getUTCDate() === Number(match[3]) ? null : "Enter a valid ISO time with Z or a UTC offset.";
21756
+ }
21757
+ const every = s.every;
21758
+ if (Number(every.minutes !== void 0) + Number(every.cron !== void 0) !== 1) return "Choose minutes or cron.";
21759
+ if (every.minutes !== void 0) return Number.isSafeInteger(every.minutes) && every.minutes > 0 ? null : "Minutes must be a positive whole number.";
21760
+ let minute;
21761
+ try {
21762
+ minute = cronFields(every.cron)[0];
21763
+ } catch (e) {
21764
+ return e.message;
21765
+ }
21766
+ const v = [...minute.values].sort((a, b) => a - b);
21767
+ const gaps = v.map((m, i) => i + 1 < v.length ? v[i + 1] - m : 60 - m + v[0]);
21768
+ return Math.min(...gaps) >= MIN_GAP_MINUTES ? null : `Cron check-ins must be at least ${MIN_GAP_MINUTES} minutes apart.`;
21769
+ }
21770
+
21367
21771
  // ../shared/src/api/digest.ts
21368
21772
  var DIGEST_ITEMS_LIMIT = 5;
21369
21773
  var digestTaskItemSchema = external_exports.object({
@@ -21505,6 +21909,50 @@ var feedbackListSchema = external_exports.object({
21505
21909
  next_cursor: external_exports.string().nullable(),
21506
21910
  total: external_exports.number().int().min(0)
21507
21911
  });
21912
+ var REPORT_SCREENSHOT_MAX_BYTES = 1572864;
21913
+ var REPORT_SCREENSHOT_DATA_URL_MAX = Math.ceil(REPORT_SCREENSHOT_MAX_BYTES / 3) * 4 + 32;
21914
+ var REPORT_MESSAGE_MAX = 1500;
21915
+ var reportBodySchema = external_exports.object({
21916
+ message: external_exports.string().trim().min(FEEDBACK_MESSAGE_MIN, `Write at least ${FEEDBACK_MESSAGE_MIN} characters`).max(REPORT_MESSAGE_MAX, `At most ${REPORT_MESSAGE_MAX} characters`),
21917
+ screenshot: external_exports.string().max(REPORT_SCREENSHOT_DATA_URL_MAX, "Screenshot is too large").optional(),
21918
+ /** Where the report came from, so the owner can reproduce it. Short strings only. */
21919
+ context: external_exports.object({
21920
+ mode: external_exports.enum(["vr", "ar", "desktop"]).optional(),
21921
+ world: external_exports.string().trim().max(60).optional(),
21922
+ url: external_exports.string().trim().max(300).optional(),
21923
+ fps: external_exports.number().min(0).max(1e3).optional()
21924
+ }).strict().optional()
21925
+ }).strict();
21926
+ var reportSentSchema = external_exports.object({ ok: external_exports.literal(true), id: entityIdSchema, screenshot: external_exports.boolean() }).strict();
21927
+
21928
+ // ../shared/src/api/talk.ts
21929
+ var TALK_UNREACHABLE = ["session_ended", "no_machine", "machine_offline", "control_off", "tool_unsupported"];
21930
+ var talkReachSchema = external_exports.union([external_exports.object({ ok: external_exports.literal(true) }), external_exports.object({ ok: external_exports.literal(false), reason: external_exports.enum(TALK_UNREACHABLE) })]);
21931
+ var talkEntrySchema = external_exports.object({
21932
+ id: external_exports.string(),
21933
+ role: external_exports.enum(["user", "agent"]),
21934
+ text: external_exports.string(),
21935
+ at: isoTimeSchema,
21936
+ /** Who sent it (user rows). */
21937
+ by: external_exports.object({ user_id: external_exports.string(), name: external_exports.string() }).optional(),
21938
+ /** The command that carried it (user rows), while that command row exists: its status shows sent -> delivered -> done / failed. */
21939
+ command: commandSchema.pick({ id: true, status: true, code: true, via: true, detail: true }).optional()
21940
+ });
21941
+ var talkResponse = external_exports.object({ reach: talkReachSchema, thread: external_exports.array(talkEntrySchema) });
21942
+
21943
+ // ../shared/src/resume.ts
21944
+ var RESUME_TOOLS = ["claude", "codex"];
21945
+ var RESUME_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
21946
+ var isResumeTool = (tool) => RESUME_TOOLS.includes(tool);
21947
+ function resumeArgv(tool, sessionId) {
21948
+ if (!sessionId || !RESUME_ID.test(sessionId) || !isResumeTool(tool)) return null;
21949
+ switch (tool) {
21950
+ case "claude":
21951
+ return ["claude", "--resume", sessionId];
21952
+ case "codex":
21953
+ return ["codex", "resume", sessionId];
21954
+ }
21955
+ }
21508
21956
 
21509
21957
  // ../shared/src/demo/script.ts
21510
21958
  var DEMO_LOOP_S = 180;
@@ -21626,20 +22074,525 @@ var meStreamPayloads = {
21626
22074
  };
21627
22075
  var ME_STREAM_EVENTS = Object.keys(meStreamPayloads);
21628
22076
 
22077
+ // ../shared/src/api/avatar.ts
22078
+ var PRESET_IDS = ["linen", "sand", "honey", "olive", "umber", "ebony"];
22079
+ var hexColor = external_exports.string().regex(/^#[0-9a-f]{6}$/i);
22080
+ var avatarSpecSchema = external_exports.object({
22081
+ v: external_exports.literal(1),
22082
+ kind: external_exports.enum(["hive", "vrm"]),
22083
+ preset: external_exports.enum(PRESET_IDS),
22084
+ colors: external_exports.object({
22085
+ skin: hexColor,
22086
+ hair: hexColor,
22087
+ top: hexColor,
22088
+ bottom: hexColor,
22089
+ accent: hexColor
22090
+ }).strict(),
22091
+ /** Hair shape, 0 through 3. */
22092
+ hair: external_exports.number().int().min(0).max(3),
22093
+ glasses: external_exports.boolean(),
22094
+ /** Outfit, 0 through 2 (tee, hoodie, jacket). */
22095
+ outfit: external_exports.number().int().min(0).max(2)
22096
+ }).strict();
22097
+ var PRESETS = [
22098
+ { v: 1, kind: "hive", preset: "linen", colors: { skin: "#f6d7c3", hair: "#c4a574", top: "#f0c14b", bottom: "#3e4c5e", accent: "#e39b2b" }, hair: 0, glasses: false, outfit: 0 },
22099
+ { v: 1, kind: "hive", preset: "sand", colors: { skin: "#e8c4a2", hair: "#6b3e26", top: "#d9784a", bottom: "#2f3b4a", accent: "#c45c26" }, hair: 1, glasses: true, outfit: 1 },
22100
+ { v: 1, kind: "hive", preset: "honey", colors: { skin: "#d7a56a", hair: "#3b2414", top: "#e8b84a", bottom: "#4a3b2a", accent: "#f2d48a" }, hair: 2, glasses: false, outfit: 2 },
22101
+ { v: 1, kind: "hive", preset: "olive", colors: { skin: "#c48a5a", hair: "#1c1c1c", top: "#5e7a4a", bottom: "#2c3330", accent: "#c9a227" }, hair: 3, glasses: true, outfit: 0 },
22102
+ { v: 1, kind: "hive", preset: "umber", colors: { skin: "#8d5524", hair: "#2a1a10", top: "#6b3a4a", bottom: "#1e2430", accent: "#d4a017" }, hair: 1, glasses: false, outfit: 1 },
22103
+ { v: 1, kind: "hive", preset: "ebony", colors: { skin: "#4a2c20", hair: "#0e0e0e", top: "#243044", bottom: "#1a1e24", accent: "#e0b050" }, hair: 2, glasses: true, outfit: 2 }
22104
+ ];
22105
+ var DEFAULT_SPEC = PRESETS[0];
22106
+ var meAvatarResponseSchema = external_exports.object({ spec: avatarSpecSchema.nullable() }).strict();
22107
+
22108
+ // ../shared/src/api/hive.ts
22109
+ var HIVE_INVITE_MAX_USES = 20;
22110
+ var iso = external_exports.string();
22111
+ var login = external_exports.string().regex(/^@?[A-Za-z0-9](?:[A-Za-z0-9-]{0,38})$/, "not a GitHub login");
22112
+ var hiveCreateInviteBody = external_exports.object({
22113
+ github_login: login.optional(),
22114
+ max_uses: external_exports.number().int().min(1).max(HIVE_INVITE_MAX_USES).optional()
22115
+ }).strict();
22116
+ var hiveInviteSchema = external_exports.object({
22117
+ id: idSchema,
22118
+ github_login: external_exports.string().nullable(),
22119
+ created_at: iso,
22120
+ expires_at: iso,
22121
+ max_uses: external_exports.number().int(),
22122
+ uses: external_exports.number().int(),
22123
+ revoked_at: iso.nullable()
22124
+ }).strict();
22125
+ var hiveCreateInviteResponse = external_exports.object({ invite: hiveInviteSchema, token: external_exports.string() }).strict();
22126
+ var hiveInviteListResponse = external_exports.object({ items: external_exports.array(hiveInviteSchema) }).strict();
22127
+ var hiveGuestSchema = external_exports.object({ user_id: idSchema, login: external_exports.string(), avatar_url: external_exports.string().nullable(), created_at: iso }).strict();
22128
+ var hiveGuestListResponse = external_exports.object({ items: external_exports.array(hiveGuestSchema) }).strict();
22129
+ var HIVE_AUDIT_ACTIONS = ["invite.create", "invite.revoke", "join", "leave", "remove", "close"];
22130
+ var hiveAuditEntrySchema = external_exports.object({
22131
+ id: idSchema,
22132
+ actor_id: idSchema.nullable(),
22133
+ actor_login: external_exports.string().nullable(),
22134
+ action: external_exports.enum(HIVE_AUDIT_ACTIONS),
22135
+ /** The invite (invite.*) or the person (join, leave, remove); null for close. */
22136
+ target_id: idSchema.nullable(),
22137
+ at: iso
22138
+ }).strict();
22139
+ var hiveAuditListResponse = external_exports.object({ items: external_exports.array(hiveAuditEntrySchema) }).strict();
22140
+ var hiveJoinBody = external_exports.union([
22141
+ external_exports.object({ token: external_exports.string().min(16).max(128) }).strict(),
22142
+ external_exports.object({ invite_id: idSchema }).strict()
22143
+ ]);
22144
+ var hiveJoinResponse = external_exports.object({ owner_id: idSchema, owner_login: external_exports.string() }).strict();
22145
+ var hiveCloseResponse = external_exports.object({ ok: external_exports.literal(true), removed: external_exports.number().int().nonnegative() }).strict();
22146
+ var hiveMembershipsResponse = external_exports.object({
22147
+ hives: external_exports.array(external_exports.object({ owner_id: idSchema, owner_login: external_exports.string(), role: external_exports.enum(["owner", "guest"]) }).strict()),
22148
+ invites: external_exports.array(external_exports.object({ id: idSchema, owner_id: idSchema, owner_login: external_exports.string(), expires_at: iso }).strict())
22149
+ }).strict();
22150
+ var hiveTurnResponse = external_exports.object({
22151
+ iceServers: external_exports.array(external_exports.object({ urls: external_exports.array(external_exports.string()), username: external_exports.string(), credential: external_exports.string() }).strict()),
22152
+ ttl: external_exports.number().int().nonnegative()
22153
+ }).strict();
22154
+ var PRESENCE_MAX_SIGNAL_BYTES = 10 * 1024;
22155
+ var PRESENCE_MAX_SDP_CHARS = 8 * 1024;
22156
+ var PRESENCE_WORLD_LIMIT_M = 40;
22157
+ var PRESENCE_DECIMALS = { position: 3, rotation: 4, blend: 2 };
22158
+ function quantise(v, decimals) {
22159
+ const f = 10 ** decimals;
22160
+ return Math.round(v * f) / f;
22161
+ }
22162
+ var isQuantised = (v, decimals) => Number.isFinite(v) && quantise(v, decimals) === v;
22163
+ var q = (decimals, min, max) => external_exports.number().min(min).max(max).refine((v) => isQuantised(v, decimals), `at most ${decimals} decimals`);
22164
+ var pos = q(PRESENCE_DECIMALS.position, -PRESENCE_WORLD_LIMIT_M, PRESENCE_WORLD_LIMIT_M);
22165
+ var rot = q(PRESENCE_DECIMALS.rotation, -1, 1);
22166
+ var yaw = q(PRESENCE_DECIMALS.rotation, -Math.PI, Math.PI);
22167
+ var blend = q(PRESENCE_DECIMALS.blend, 0, 1);
22168
+ var unitQuat = (q4) => Math.abs(Math.hypot(q4[0], q4[1], q4[2], q4[3]) - 1) <= 1e-3;
22169
+ var posQuat = external_exports.tuple([pos, pos, pos, rot, rot, rot, rot]).refine((t) => unitQuat(t.slice(3)), "quaternion is not unit length");
22170
+ var PRESENCE_FACE_KEYS = [
22171
+ "jawOpen",
22172
+ "mouthClose",
22173
+ "mouthFunnel",
22174
+ "mouthPucker",
22175
+ "mouthSmileLeft",
22176
+ "mouthSmileRight",
22177
+ "eyeBlinkLeft",
22178
+ "eyeBlinkRight",
22179
+ "browInnerUp",
22180
+ "browDownLeft",
22181
+ "browDownRight",
22182
+ "cheekPuff"
22183
+ ];
22184
+ var faceSchema = external_exports.object(Object.fromEntries(PRESENCE_FACE_KEYS.map((k) => [k, blend.optional()]))).strict();
22185
+ var u31 = external_exports.number().int().min(0).max(2 ** 31 - 1);
22186
+ var poseFields = {
22187
+ seq: u31,
22188
+ /** Sender clock, ms; only for ordering and interpolation on the receiver. */
22189
+ t: u31,
22190
+ root: external_exports.tuple([pos, pos, pos, yaw]),
22191
+ head: posQuat,
22192
+ lh: posQuat.nullable(),
22193
+ rh: posQuat.nullable(),
22194
+ fingers: external_exports.array(blend).length(10).nullable(),
22195
+ face: faceSchema.nullable(),
22196
+ speaking: external_exports.union([external_exports.literal(0), external_exports.literal(1)])
22197
+ };
22198
+ var userId = idSchema;
22199
+ var sdp = external_exports.string().min(1).max(PRESENCE_MAX_SDP_CHARS);
22200
+ var iceCandidate = external_exports.object({
22201
+ candidate: external_exports.string().max(512),
22202
+ sdpMid: external_exports.string().max(32).nullable(),
22203
+ sdpMLineIndex: external_exports.number().int().min(0).max(31).nullable()
22204
+ }).strict();
22205
+ var signalFields = (extra) => [
22206
+ external_exports.object({ type: external_exports.literal("signal"), ...extra, kind: external_exports.literal("offer"), sdp }).strict(),
22207
+ external_exports.object({ type: external_exports.literal("signal"), ...extra, kind: external_exports.literal("answer"), sdp }).strict(),
22208
+ external_exports.object({ type: external_exports.literal("signal"), ...extra, kind: external_exports.literal("ice"), candidate: iceCandidate }).strict()
22209
+ ];
22210
+ var presenceHelloSchema = external_exports.object({ type: external_exports.literal("hello"), avatar: avatarSpecSchema }).strict();
22211
+ var presencePoseSchema = external_exports.object({ type: external_exports.literal("pose"), ...poseFields }).strict();
22212
+ var presenceSignalSchema = external_exports.union(signalFields({ to: userId }));
22213
+ var presenceLeaveSchema = external_exports.object({ type: external_exports.literal("leave") }).strict();
22214
+ var presenceClientMessage = external_exports.union([presenceHelloSchema, presencePoseSchema, presenceSignalSchema, presenceLeaveSchema]);
22215
+ var presenceMemberSchema = external_exports.object({ id: userId, login: external_exports.string().max(39), avatar: avatarSpecSchema.nullable(), role: external_exports.enum(["owner", "guest"]) }).strict();
22216
+ var presenceServerMessage = external_exports.union([
22217
+ /** First frame after the upgrade: who you are and who is here (including you). */
22218
+ external_exports.object({ type: external_exports.literal("roster"), you: userId, members: external_exports.array(presenceMemberSchema) }).strict(),
22219
+ /** Someone arrived or changed their avatar (an upsert). */
22220
+ external_exports.object({ type: external_exports.literal("join"), member: presenceMemberSchema }).strict(),
22221
+ external_exports.object({ type: external_exports.literal("leave"), id: userId }).strict(),
22222
+ external_exports.object({ type: external_exports.literal("pose"), from: userId, ...poseFields }).strict(),
22223
+ ...signalFields({ from: userId }),
22224
+ /** Sent just before the server closes this socket. */
22225
+ external_exports.object({ type: external_exports.literal("kick"), reason: external_exports.enum(["removed", "closed", "replaced"]) }).strict()
22226
+ ]);
22227
+
22228
+ // ../shared/src/api/orchestrator-stream.ts
22229
+ var ORCH_RUNTIMES = ["claude", "codex", "cursor"];
22230
+ var orchRuntimeSchema = external_exports.enum(ORCH_RUNTIMES);
22231
+ var ORCH_MODES = ["spawned", "attached"];
22232
+ var ORCH_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
22233
+ var ORCH_POWERS = ["safe", "full"];
22234
+ var ORCH_PERMISSION_MODES = ["default", "acceptEdits", "bypassPermissions"];
22235
+ var ORCH_CWD_MODES = ["auto", "stable"];
22236
+ var ORCH_STATES = ["starting", "idle", "working", "waiting_input", "stopped", "crashed"];
22237
+ var ORCH_LIMITS = {
22238
+ messageText: 32e3,
22239
+ sendText: 4e3,
22240
+ /** The first message of a fresh session (`brief`), in UTF-8 bytes. */
22241
+ briefBytes: 16 * 1024,
22242
+ toolSummary: 2048,
22243
+ thinkingText: 8e3,
22244
+ questionSummary: 1024,
22245
+ optionCount: 8,
22246
+ optionText: 200,
22247
+ errorMessage: 1e3,
22248
+ batch: 100,
22249
+ /** An answer to a question times out into a deny after this long. */
22250
+ questionTimeoutSec: 600,
22251
+ /** A `send` to a machine not seen this recently answers 409 `machine_offline`. */
22252
+ machineOfflineSec: 60,
22253
+ /** A queued orchestrator command not taken by the machine in this time expires. */
22254
+ commandTtlSec: 120,
22255
+ historyDays: 30,
22256
+ historyMaxEvents: 5e3
22257
+ };
22258
+ var id = external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,127}$/, "an id");
22259
+ var modelId = external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:/[\]-]{0,99}$/, "a model id");
22260
+ var str = (max) => external_exports.string().max(max);
22261
+ var ORCH_EVENT_TYPES = ["message", "thinking", "tool_use", "tool_result", "status", "question", "error", "usage"];
22262
+ var messageBody = external_exports.strictObject({
22263
+ role: external_exports.enum(["assistant", "user"]),
22264
+ text: str(ORCH_LIMITS.messageText),
22265
+ msg_id: id,
22266
+ /** Set on user rows, which the server writes itself when it accepts a `send`. */
22267
+ from: external_exports.strictObject({ user_id: idSchema, name: str(100) }).optional(),
22268
+ /** Set when the server sent the row for the user: a batch of fleet reports, or a scheduled check-in. */
22269
+ via: external_exports.enum(["bridge", "schedule"]).optional()
22270
+ });
22271
+ var machineMessageBody = messageBody.omit({ from: true, role: true, via: true }).extend({ role: external_exports.literal("assistant") });
22272
+ var thinkingBody = external_exports.strictObject({ text: str(ORCH_LIMITS.thinkingText) });
22273
+ var toolUseBody = external_exports.strictObject({ tool_use_id: id, name: str(100), input_summary: str(ORCH_LIMITS.toolSummary) });
22274
+ var toolResultBody = external_exports.strictObject({ tool_use_id: id, ok: external_exports.boolean(), summary: str(ORCH_LIMITS.toolSummary) });
22275
+ var statusBody = external_exports.strictObject({
22276
+ state: external_exports.enum(ORCH_STATES),
22277
+ detail: str(300).optional(),
22278
+ /** The runtime's own session id (Claude's `system/init`), kept so a restart can `--resume` it. */
22279
+ external_id: id.optional()
22280
+ });
22281
+ var questionBody = external_exports.strictObject({
22282
+ question_id: external_exports.string().regex(/^[A-Za-z0-9_-]{8,128}$/, "a question id"),
22283
+ kind: external_exports.enum(["permission", "ask"]),
22284
+ tool: str(100).optional(),
22285
+ summary: str(ORCH_LIMITS.questionSummary),
22286
+ options: external_exports.array(str(ORCH_LIMITS.optionText)).max(ORCH_LIMITS.optionCount).optional()
22287
+ });
22288
+ var errorBody = external_exports.strictObject({ code: str(60), message: str(ORCH_LIMITS.errorMessage) });
22289
+ var usageBody = external_exports.strictObject({
22290
+ input_tokens: external_exports.number().int().nonnegative(),
22291
+ output_tokens: external_exports.number().int().nonnegative(),
22292
+ cache_read: external_exports.number().int().nonnegative().optional(),
22293
+ cost_usd: external_exports.number().nonnegative().optional(),
22294
+ duration_ms: external_exports.number().int().nonnegative()
22295
+ });
22296
+ var orchEventIn = external_exports.discriminatedUnion("type", [
22297
+ external_exports.strictObject({ src_seq: external_exports.number().int().positive(), type: external_exports.literal("message"), body: machineMessageBody }),
22298
+ external_exports.strictObject({ src_seq: external_exports.number().int().positive(), type: external_exports.literal("thinking"), body: thinkingBody }),
22299
+ external_exports.strictObject({ src_seq: external_exports.number().int().positive(), type: external_exports.literal("tool_use"), body: toolUseBody }),
22300
+ external_exports.strictObject({ src_seq: external_exports.number().int().positive(), type: external_exports.literal("tool_result"), body: toolResultBody }),
22301
+ external_exports.strictObject({ src_seq: external_exports.number().int().positive(), type: external_exports.literal("status"), body: statusBody }),
22302
+ external_exports.strictObject({ src_seq: external_exports.number().int().positive(), type: external_exports.literal("question"), body: questionBody }),
22303
+ external_exports.strictObject({ src_seq: external_exports.number().int().positive(), type: external_exports.literal("error"), body: errorBody }),
22304
+ external_exports.strictObject({ src_seq: external_exports.number().int().positive(), type: external_exports.literal("usage"), body: usageBody })
22305
+ ]);
22306
+ var orchEventsBatchBody = external_exports.strictObject({ events: external_exports.array(orchEventIn).min(1).max(ORCH_LIMITS.batch) });
22307
+ var orchEventsAckSchema = external_exports.strictObject({ acked_src_seq: external_exports.number().int().nonnegative() });
22308
+ var orchEventSchema = external_exports.object({
22309
+ seq: external_exports.number().int().positive(),
22310
+ at: isoTimeSchema,
22311
+ type: external_exports.enum(ORCH_EVENT_TYPES),
22312
+ body: external_exports.record(external_exports.string(), external_exports.unknown())
22313
+ });
22314
+ var orchHistorySchema = external_exports.object({ events: external_exports.array(orchEventSchema), has_more: external_exports.boolean() });
22315
+ var orchRuntimeInfoSchema = external_exports.strictObject({
22316
+ runtime: orchRuntimeSchema,
22317
+ version: str(40).optional(),
22318
+ logins: external_exports.array(external_exports.strictObject({
22319
+ id,
22320
+ label: str(120),
22321
+ /** Whether this login can start a session. A service from before this field leaves it out. Never a token or an email. */
22322
+ usage: external_exports.enum(["ok", "limited"]).optional(),
22323
+ /** When a limited login expects to be free again, in the machine's own short words. */
22324
+ resets: str(40).optional()
22325
+ })).max(20)
22326
+ });
22327
+ var orchRuntimesSchema = external_exports.array(orchRuntimeInfoSchema).max(3);
22328
+ var orchMachineInfoBody = external_exports.strictObject({
22329
+ enabled: external_exports.boolean(),
22330
+ runtimes: orchRuntimesSchema,
22331
+ /**
22332
+ * True only after the machine's owner ran `hivefloor orch enable --full` on it. The server never sets it: it is the
22333
+ * local consent to full power. A service older than this field leaves it out.
22334
+ */
22335
+ full_allowed: external_exports.boolean().optional()
22336
+ });
22337
+ var orchCapabilitiesSchema = external_exports.strictObject({ answer: external_exports.boolean(), interrupt: external_exports.boolean() });
22338
+ var briefText = external_exports.string().transform((s, ctx) => {
22339
+ const t = cleanOrchText(s).trim();
22340
+ if (t === "" || new TextEncoder().encode(t).length > ORCH_LIMITS.briefBytes) {
22341
+ ctx.addIssue({ code: "custom", message: `must be 1 to ${ORCH_LIMITS.briefBytes} bytes` });
22342
+ return external_exports.NEVER;
22343
+ }
22344
+ return t;
22345
+ });
22346
+ var startOptions = {
22347
+ power: external_exports.enum(ORCH_POWERS).optional(),
22348
+ /** Full power only. */
22349
+ permission_mode: external_exports.enum(ORCH_PERMISSION_MODES).optional(),
22350
+ /** Full power only: start Claude Code with `--chrome`. */
22351
+ chrome: external_exports.boolean().optional(),
22352
+ /** Keep the machine awake while the session's process lives (macOS; ignored elsewhere). */
22353
+ keep_awake: external_exports.boolean().optional(),
22354
+ /** `mode: 'attached'` only. */
22355
+ cwd: external_exports.enum(ORCH_CWD_MODES).optional()
22356
+ };
22357
+ var configureSessionBody = external_exports.strictObject({
22358
+ machine_id: idSchema,
22359
+ runtime: orchRuntimeSchema,
22360
+ model: modelId,
22361
+ effort: external_exports.enum(ORCH_EFFORTS),
22362
+ login_id: id.optional(),
22363
+ mode: external_exports.enum(ORCH_MODES).default("spawned"),
22364
+ /** The runtime's own session id, for `mode: 'attached'`: the session to resume. */
22365
+ external_id: id.optional(),
22366
+ ...startOptions,
22367
+ /** `mode: 'spawned'` only: starts a new session (never resumes the last one) and sends this as its first message. */
22368
+ brief: briefText.optional()
22369
+ }).superRefine((v, ctx) => {
22370
+ const full = v.power === "full";
22371
+ if (v.mode === "attached" && !v.external_id) ctx.addIssue({ code: "custom", path: ["external_id"], message: "attach needs the session to attach to" });
22372
+ if (v.mode === "spawned" && v.external_id) ctx.addIssue({ code: "custom", path: ["external_id"], message: "only attach takes a session id" });
22373
+ if (v.mode === "attached" && !full) ctx.addIssue({ code: "custom", path: ["power"], message: "attach needs full power" });
22374
+ if (!full && v.permission_mode !== void 0 && v.permission_mode !== "default") ctx.addIssue({ code: "custom", path: ["permission_mode"], message: "only full power takes a permission mode" });
22375
+ if (!full && v.chrome === true) ctx.addIssue({ code: "custom", path: ["chrome"], message: "only full power takes chrome" });
22376
+ if (v.mode !== "attached" && v.cwd !== void 0 && v.cwd !== "auto") ctx.addIssue({ code: "custom", path: ["cwd"], message: "only attach takes a folder choice" });
22377
+ if (v.mode === "attached" && v.brief !== void 0) ctx.addIssue({ code: "custom", path: ["brief"], message: "only a new session takes a brief" });
22378
+ });
22379
+ var orchSessionViewSchema = external_exports.object({
22380
+ id: external_exports.string(),
22381
+ machine: external_exports.object({ id: external_exports.string(), name: external_exports.string() }),
22382
+ runtime: orchRuntimeSchema,
22383
+ model: external_exports.string(),
22384
+ effort: external_exports.enum(ORCH_EFFORTS),
22385
+ login_label: external_exports.string().nullable(),
22386
+ mode: external_exports.enum(ORCH_MODES),
22387
+ power: external_exports.enum(ORCH_POWERS).optional(),
22388
+ permission_mode: external_exports.enum(ORCH_PERMISSION_MODES).optional(),
22389
+ chrome: external_exports.boolean().optional(),
22390
+ keep_awake: external_exports.boolean().optional(),
22391
+ cwd: external_exports.enum(ORCH_CWD_MODES).optional(),
22392
+ state: external_exports.enum(ORCH_STATES),
22393
+ /** False while the machine has not been seen for `machineOfflineSec`. */
22394
+ machine_online: external_exports.boolean(),
22395
+ /** When the machine last reported (o159 G: the health banner says how long it has been asleep). */
22396
+ machine_last_seen_at: isoTimeSchema.nullable().optional(),
22397
+ /** Stopped or crashed, spawned, and the runtime gave its own session id: `POST /orchestrator/session/resume` continues that same session. */
22398
+ resumable: external_exports.boolean().optional(),
22399
+ capabilities: orchCapabilitiesSchema,
22400
+ last_event_seq: external_exports.number().int().nonnegative(),
22401
+ created_at: isoTimeSchema
22402
+ });
22403
+ var orchSessionResponseSchema = external_exports.object({ session: orchSessionViewSchema.nullable() });
22404
+ var ORCH_MACHINE_REASONS = ["offline", "orch_off", "no_claude"];
22405
+ var orchMachineReasonSchema = external_exports.enum(ORCH_MACHINE_REASONS);
22406
+ var orchOptionsSchema = external_exports.object({
22407
+ machines: external_exports.array(external_exports.object({ id: external_exports.string(), name: external_exports.string(), online: external_exports.boolean(), orchestrator_enabled: external_exports.boolean(), full_allowed: external_exports.boolean().optional(), runtimes: orchRuntimesSchema, reason: orchMachineReasonSchema.optional().catch(void 0) })),
22408
+ models: external_exports.record(orchRuntimeSchema, external_exports.array(external_exports.strictObject({ id: external_exports.string(), label: external_exports.string() }))),
22409
+ efforts: external_exports.array(external_exports.enum(ORCH_EFFORTS))
22410
+ });
22411
+ var idempotencyKey = external_exports.string().min(8).max(64);
22412
+ function cleanOrchText(input2) {
22413
+ return input2.normalize("NFC").replace(/\r\n?/g, "\n").replace(/[\u0000-\u0008\u000B-\u001F\u007F-\u009F]/g, "");
22414
+ }
22415
+ var sendText = external_exports.string().transform((s, ctx) => {
22416
+ const t = cleanOrchText(s).trim();
22417
+ if (t === "" || Array.from(t).length > ORCH_LIMITS.sendText) {
22418
+ ctx.addIssue({ code: "custom", message: `must be 1 to ${ORCH_LIMITS.sendText} characters` });
22419
+ return external_exports.NEVER;
22420
+ }
22421
+ return t;
22422
+ });
22423
+ var sendBody = external_exports.strictObject({ text: sendText, idempotency_key: idempotencyKey });
22424
+ var answerBody = external_exports.strictObject({ question_id: questionBody.shape.question_id, choice: str(ORCH_LIMITS.optionText).min(1), idempotency_key: idempotencyKey });
22425
+ var orchCommandSchema = external_exports.discriminatedUnion("kind", [
22426
+ external_exports.strictObject({
22427
+ id: external_exports.string(),
22428
+ orch_id: external_exports.string(),
22429
+ kind: external_exports.literal("orch_start"),
22430
+ args: external_exports.strictObject({
22431
+ runtime: orchRuntimeSchema,
22432
+ model: modelId,
22433
+ effort: external_exports.enum(ORCH_EFFORTS),
22434
+ login_id: id.nullable(),
22435
+ /** The session to `--resume` after a restart (reported earlier as `status.external_id`). */
22436
+ resume_id: id.nullable(),
22437
+ mode: external_exports.enum(ORCH_MODES),
22438
+ external_id: id.nullable(),
22439
+ ...startOptions,
22440
+ /** Sent as the first message when the session starts new (never on a resume). Already cleaned by the server; the machine cleans it again. */
22441
+ brief: external_exports.string().max(ORCH_LIMITS.briefBytes).nullable().optional()
22442
+ })
22443
+ }),
22444
+ external_exports.strictObject({ id: external_exports.string(), orch_id: external_exports.string(), kind: external_exports.literal("orch_send"), args: external_exports.strictObject({ text: external_exports.string(), msg_id: id }) }),
22445
+ external_exports.strictObject({ id: external_exports.string(), orch_id: external_exports.string(), kind: external_exports.literal("orch_answer"), args: external_exports.strictObject({ question_id: external_exports.string(), choice: external_exports.string() }) }),
22446
+ external_exports.strictObject({ id: external_exports.string(), orch_id: external_exports.string(), kind: external_exports.literal("orch_interrupt"), args: external_exports.strictObject({}) }),
22447
+ external_exports.strictObject({ id: external_exports.string(), orch_id: external_exports.string(), kind: external_exports.literal("orch_stop"), args: external_exports.strictObject({}) })
22448
+ ]);
22449
+ var orchCommandsResponseSchema = external_exports.object({ commands: external_exports.array(orchCommandSchema).max(10) });
22450
+
22451
+ // ../shared/src/api/orch-bridge.ts
22452
+ var ORCH_BRIDGE_LIMITS = {
22453
+ linesPerPost: 20,
22454
+ lineText: 2e3,
22455
+ /** Lines waiting for one user; past this a post is refused until delivery catches up. */
22456
+ pendingPerUser: 500,
22457
+ /** Same tag and text again within this window is a duplicate. */
22458
+ dedupeHours: 24,
22459
+ minGapMs: 6e5,
22460
+ /** NEEDS-YOU / URGENT may wake the session inside the gap at most this often per hour; past it they wait for the gap. */
22461
+ priorityWakesPerHour: 6,
22462
+ /** Undelivered reports older than this are dropped, so a long stop does not replay stale news. */
22463
+ pendingHours: 24,
22464
+ schedulesPerUser: 50,
22465
+ schedulePrompt: 3900,
22466
+ /** Check-ins one schedule may send per UTC day, whatever its rule says. */
22467
+ firesPerDay: 96,
22468
+ /** A due check-in waits for idle this long, then is skipped for that slot. */
22469
+ lateMs: 15 * 6e4
22470
+ };
22471
+ var ORCH_SCHEDULE_TARGETS = ["orchestrator"];
22472
+ var bridgeLineSchema = external_exports.strictObject({
22473
+ tag: external_exports.string().regex(/^[A-Z0-9_-]{1,32}$/),
22474
+ text: external_exports.string().trim().min(1).max(ORCH_BRIDGE_LIMITS.lineText).refine((t) => !/[\r\n]/.test(t), "One line only."),
22475
+ at: external_exports.iso.datetime({ offset: true }).optional()
22476
+ });
22477
+ var bridgeBody = external_exports.strictObject({ lines: external_exports.array(bridgeLineSchema).min(1).max(ORCH_BRIDGE_LIMITS.linesPerPost) });
22478
+ var bridgeResponseSchema = external_exports.object({ accepted: external_exports.number().int(), duplicates: external_exports.number().int() });
22479
+ var scheduleIdSchema = external_exports.string().regex(/^[A-Za-z0-9_-]{8,64}$/);
22480
+ var scheduleBody = external_exports.strictObject({
22481
+ sessionTarget: external_exports.enum(ORCH_SCHEDULE_TARGETS),
22482
+ prompt: external_exports.string().max(ORCH_BRIDGE_LIMITS.schedulePrompt),
22483
+ at: external_exports.string().max(40).optional(),
22484
+ every: external_exports.strictObject({ minutes: external_exports.number().int().min(5).max(7 * 24 * 60).optional(), cron: external_exports.string().max(120).optional() }).optional(),
22485
+ tz: external_exports.string().min(1).max(64),
22486
+ enabled: external_exports.boolean()
22487
+ }).superRefine((s, ctx) => {
22488
+ const err = scheduleError({ id: "x", ...s });
22489
+ if (err) ctx.addIssue({ code: "custom", message: err });
22490
+ });
22491
+ var scheduleToggleBody = external_exports.strictObject({ enabled: external_exports.boolean() });
22492
+
22493
+ // ../shared/src/profile.ts
22494
+ var HEATMAP_METRICS = ["sessions", "agent_hours"];
22495
+ var heatmapMetricSchema = external_exports.enum(HEATMAP_METRICS);
22496
+ var profileSettingsSchema = external_exports.object({
22497
+ published: external_exports.boolean(),
22498
+ show_name: external_exports.boolean(),
22499
+ show_heatmap: external_exports.boolean(),
22500
+ show_totals: external_exports.boolean(),
22501
+ show_providers: external_exports.boolean(),
22502
+ show_live: external_exports.boolean(),
22503
+ indexable: external_exports.boolean(),
22504
+ include_team_activity: external_exports.boolean(),
22505
+ heatmap_metric: heatmapMetricSchema,
22506
+ record_history: external_exports.boolean()
22507
+ }).strict();
22508
+ var LISTING_FLAGS = ["listable", "hidden"];
22509
+ var listingFlagSchema = external_exports.enum(LISTING_FLAGS);
22510
+ var meListedProjectSchema = external_exports.object({
22511
+ project_id: idSchema,
22512
+ listing: listingFlagSchema
22513
+ }).strict();
22514
+ var meProfileResponseSchema = profileSettingsSchema.extend({
22515
+ projects: external_exports.array(meListedProjectSchema)
22516
+ }).strict();
22517
+ var listedProjectsBody = external_exports.object({ project_ids: external_exports.array(idSchema).max(200) }).strict();
22518
+ var deleteActivityBody = external_exports.object({ login: external_exports.string().min(1).max(39) }).strict();
22519
+ var heatmapSchema2 = external_exports.object({
22520
+ metric: heatmapMetricSchema,
22521
+ days: external_exports.array(external_exports.object({ day: external_exports.string(), value: external_exports.number() }).strict())
22522
+ }).strict();
22523
+ var totalsSchema = external_exports.object({
22524
+ sessions_started: external_exports.number(),
22525
+ sessions_finished: external_exports.number(),
22526
+ agent_hours: external_exports.number(),
22527
+ machines: external_exports.number(),
22528
+ longest_streak: external_exports.number(),
22529
+ current_streak: external_exports.number()
22530
+ }).strict();
22531
+ var providerSchema2 = external_exports.object({ tool: external_exports.string(), sessions: external_exports.number(), agent_hours: external_exports.number() }).strict();
22532
+ var listedProjectSchema = external_exports.object({ name: external_exports.string(), sessions: external_exports.number(), agent_hours: external_exports.number() }).strict();
22533
+ var publicProfileSchema = external_exports.object({
22534
+ login: external_exports.string(),
22535
+ avatar_url: external_exports.string().nullable(),
22536
+ since: external_exports.string(),
22537
+ name: external_exports.string().optional(),
22538
+ heatmap: heatmapSchema2.optional(),
22539
+ totals: totalsSchema.optional(),
22540
+ providers: external_exports.array(providerSchema2).optional(),
22541
+ projects: external_exports.array(listedProjectSchema).optional()
22542
+ }).strict();
22543
+ var liveSummarySchema = external_exports.object({
22544
+ agents: external_exports.number().int().nonnegative(),
22545
+ machines: external_exports.number().int().nonnegative(),
22546
+ as_of: external_exports.string()
22547
+ }).strict();
22548
+
21629
22549
  // ../shared/src/index.ts
21630
22550
  var ROLES = ["owner", "admin", "member", "viewer"];
21631
22551
  var roleSchema2 = external_exports.enum(ROLES);
21632
22552
 
21633
22553
  export {
22554
+ NEVER,
22555
+ safeParse,
22556
+ string2 as string,
22557
+ url,
22558
+ number2 as number,
22559
+ boolean2 as boolean,
22560
+ _null3 as _null,
22561
+ any,
22562
+ unknown,
22563
+ array,
22564
+ object,
22565
+ looseObject,
22566
+ union,
22567
+ discriminatedUnion,
22568
+ intersection,
22569
+ record,
22570
+ _enum2 as _enum,
22571
+ literal,
22572
+ optional,
22573
+ custom,
22574
+ preprocess,
22575
+ ZodIssueCode,
22576
+ iso_exports,
22577
+ coerce_exports,
21634
22578
  normalizeRemote,
21635
22579
  formatRemote,
21636
22580
  deviceCodeResponseSchema,
21637
22581
  deviceTokenErrorSchema,
21638
22582
  deviceTokenSuccessSchema,
21639
22583
  HOOK_BATCH_MAX,
22584
+ CONTROL_REPLY_MAX,
22585
+ PEEK_LINES_MAX,
22586
+ PEEK_OUTPUT_MAX,
22587
+ stripControlChars,
22588
+ cleanControlText,
22589
+ machineCommandsResponse,
22590
+ machinePromptResponse,
21640
22591
  MACHINE_HEARTBEAT_SECONDS,
21641
22592
  MACHINE_MIN_INTERVAL_SECONDS,
21642
22593
  PROFILE_KEY_RE,
22594
+ ENDED_SESSION_ID_RE,
22595
+ ENDED_SESSIONS_MAX,
21643
22596
  machineHeartbeatResponseSchema,
21644
22597
  SESSION_ACCOUNT_RE,
21645
22598
  machineTokenSuccessSchema,
@@ -21654,5 +22607,14 @@ export {
21654
22607
  usageRouteSchema,
21655
22608
  KOKORO_VOICES,
21656
22609
  voiceFor,
21657
- KOKORO_VOICE_ID
22610
+ KOKORO_VOICE_ID,
22611
+ RESUME_ID,
22612
+ isResumeTool,
22613
+ resumeArgv,
22614
+ ORCH_PERMISSION_MODES,
22615
+ ORCH_LIMITS,
22616
+ orchEventIn,
22617
+ cleanOrchText,
22618
+ orchCommandSchema,
22619
+ orchCommandsResponseSchema
21658
22620
  };