zelari-code 1.47.2 → 1.48.0

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.
@@ -20,6 +20,7 @@ import { startPermissionBroker, } from "../mcp/permissionBroker.js";
20
20
  import { createBrokerPermissionHandler, createBrokerQuestionHandler, } from "../mcp/brokerHandlers.js";
21
21
  import { createPermissionAskHandler } from "./permissionPicker.js";
22
22
  import { appendSystem } from "./messageHelpers.js";
23
+ import { armPickerTimeout, askUserTimeoutMs } from "./askUserTimeout.js";
23
24
  export function usePermissionBroker(opts) {
24
25
  const { setPicker, setMessages } = opts;
25
26
  const handleRef = useRef(null);
@@ -42,13 +43,22 @@ export function usePermissionBroker(opts) {
42
43
  return;
43
44
  }
44
45
  let settled = false;
46
+ let cancelWaitTimeout;
45
47
  const finish = (value) => {
46
48
  if (settled)
47
49
  return;
48
50
  settled = true;
51
+ cancelWaitTimeout?.();
49
52
  setPicker(null);
50
53
  resolve(value);
51
54
  };
55
+ // v1.47.x: timeout so an unseen external-agent question cannot block
56
+ // the broker client forever. Knob: ZELARI_ASK_USER_TIMEOUT_MS.
57
+ const waitTimeoutMs = askUserTimeoutMs();
58
+ cancelWaitTimeout = armPickerTimeout(() => {
59
+ appendSystem(setMessages, `[external agent] nessuna risposta entro ${Math.round(waitTimeoutMs / 1000)}s — richiesta annullata.`, Date.now());
60
+ finish(null);
61
+ }, waitTimeoutMs);
52
62
  appendSystem(setMessages, `[external agent] ${req.question}\n→ ${choices.join(" · ")}`, Date.now());
53
63
  setPicker({
54
64
  kind: "clarification",
@@ -1 +1 @@
1
- {"version":3,"file":"usePermissionBroker.js","sourceRoot":"","sources":["../../../src/cli/hooks/usePermissionBroker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"usePermissionBroker.js","sourceRoot":"","sources":["../../../src/cli/hooks/usePermissionBroker.ts"],"names":[],"mappings":"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"}
@@ -628,7 +628,12 @@ async function refreshGrokToken(options) {
628
628
  grant_type: "refresh_token",
629
629
  client_id: options.clientId,
630
630
  refresh_token: options.refreshToken
631
- }).toString()
631
+ }).toString(),
632
+ // v1.47.x: hard 30s cap. A hung auth socket used to freeze the whole
633
+ // turn on "working" forever with no error (the refresh promise never
634
+ // settled). A visible failure is strictly better: callers fall back
635
+ // to the current token and surface the error.
636
+ signal: AbortSignal.timeout(3e4)
632
637
  });
633
638
  } catch (err) {
634
639
  throw new GrokOAuthError(
@@ -48395,9 +48400,17 @@ function WorkingIndicator({
48395
48400
  // src/cli/components/LiveRegion.tsx
48396
48401
  var LIVE_STREAM_TAIL_LINES = 10;
48397
48402
  var MAX_LIVE_TOOLS = 4;
48398
- function LiveRegion({ live, busy, elapsedMs = null }) {
48403
+ function LiveRegion({
48404
+ live,
48405
+ busy,
48406
+ elapsedMs = null,
48407
+ waitingForUser = false,
48408
+ waitingSinceMs = 0
48409
+ }) {
48399
48410
  const { streaming, runningTools } = live;
48400
- if (!streaming && runningTools.length === 0 && !busy) return null;
48411
+ if (!streaming && runningTools.length === 0 && !busy && !waitingForUser) {
48412
+ return null;
48413
+ }
48401
48414
  const visibleTools = runningTools.slice(0, MAX_LIVE_TOOLS);
48402
48415
  const hiddenTools = runningTools.length - visibleTools.length;
48403
48416
  return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column", paddingX: 1 }, streaming && streaming.role === "assistant" && /* @__PURE__ */ React5.createElement(
@@ -48409,7 +48422,7 @@ function LiveRegion({ live, busy, elapsedMs = null }) {
48409
48422
  memberName: streaming.memberName,
48410
48423
  memberId: streaming.memberId
48411
48424
  }
48412
- ), visibleTools.map((t) => /* @__PURE__ */ React5.createElement(Box4, { key: t.id, flexDirection: "column" }, renderMessage(t, true))), hiddenTools > 0 ? /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, " \u2026 +", hiddenTools, " more tools") : null, busy && runningTools.length === 0 && !streaming && /* @__PURE__ */ React5.createElement(WorkingIndicator, { elapsedMs }));
48425
+ ), visibleTools.map((t) => /* @__PURE__ */ React5.createElement(Box4, { key: t.id, flexDirection: "column" }, renderMessage(t, true))), hiddenTools > 0 ? /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, " \u2026 +", hiddenTools, " more tools") : null, waitingForUser && /* @__PURE__ */ React5.createElement(Text5, { color: "yellow", bold: true }, "\u23F8 In attesa della TUA risposta", waitingSinceMs > 0 ? ` (${Math.floor(Math.max(0, Date.now() - waitingSinceMs) / 1e3)}s)` : "", " \u2014 \u2191/\u2193 + Invio \xB7 Esc = annulla"), busy && runningTools.length === 0 && !streaming && !waitingForUser && /* @__PURE__ */ React5.createElement(WorkingIndicator, { elapsedMs }));
48413
48426
  }
48414
48427
  function StreamingTail(m) {
48415
48428
  const lines = m.content.split("\n");
@@ -51259,6 +51272,22 @@ init_taskTool();
51259
51272
 
51260
51273
  // src/cli/hooks/permissionPicker.ts
51261
51274
  init_toolPermissions();
51275
+
51276
+ // src/cli/hooks/askUserTimeout.ts
51277
+ function askUserTimeoutMs() {
51278
+ const raw = process.env.ZELARI_ASK_USER_TIMEOUT_MS?.trim();
51279
+ if (!raw) return 3e5;
51280
+ const n = Number.parseInt(raw, 10);
51281
+ if (!Number.isFinite(n) || n < 0) return 3e5;
51282
+ return n;
51283
+ }
51284
+ function armPickerTimeout(onFire, ms) {
51285
+ if (ms <= 0) return () => void 0;
51286
+ const id = setTimeout(onFire, ms);
51287
+ return () => clearTimeout(id);
51288
+ }
51289
+
51290
+ // src/cli/hooks/permissionPicker.ts
51262
51291
  function createPermissionAskHandler(opts) {
51263
51292
  const { setPicker: setPicker2, appendSystem: appendSystem2 } = opts;
51264
51293
  return (req) => new Promise((resolve3) => {
@@ -51273,13 +51302,25 @@ ${detail}
51273
51302
  Date.now()
51274
51303
  );
51275
51304
  let settled = false;
51305
+ const askTimeoutMs = askUserTimeoutMs();
51306
+ let cancelAskTimeout = () => void 0;
51276
51307
  const finish = (ok, note) => {
51277
51308
  if (settled) return;
51278
51309
  settled = true;
51310
+ cancelAskTimeout();
51279
51311
  setPicker2(null);
51280
51312
  if (note) appendSystem2?.(note, Date.now());
51281
51313
  resolve3(ok);
51282
51314
  };
51315
+ cancelAskTimeout = armPickerTimeout(
51316
+ () => finish(
51317
+ false,
51318
+ `[permission] ask for "${req.toolName}" timed out after ${Math.round(
51319
+ askTimeoutMs / 1e3
51320
+ )}s \u2014 denied (tool can be re-run). Knob: ZELARI_ASK_USER_TIMEOUT_MS.`
51321
+ ),
51322
+ askTimeoutMs
51323
+ );
51283
51324
  const items = [
51284
51325
  { value: "allow", label: "Allow once" },
51285
51326
  {
@@ -51629,12 +51670,28 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
51629
51670
  Date.now()
51630
51671
  );
51631
51672
  let settled = false;
51673
+ const askTimeoutMs = askUserTimeoutMs();
51674
+ let cancelAskTimeout = () => void 0;
51632
51675
  const finish = (value) => {
51633
51676
  if (settled) return;
51634
51677
  settled = true;
51678
+ cancelAskTimeout();
51635
51679
  setPicker2(null);
51636
51680
  resolve3(value);
51637
51681
  };
51682
+ cancelAskTimeout = armPickerTimeout(
51683
+ () => {
51684
+ appendSystem(
51685
+ setMessages,
51686
+ `[ask_user] nessuna risposta entro ${Math.round(
51687
+ askTimeoutMs / 1e3
51688
+ )}s \u2014 proseguo con assunzione documentata (ZELARI_ASK_USER_TIMEOUT_MS).`,
51689
+ Date.now()
51690
+ );
51691
+ finish(null);
51692
+ },
51693
+ askTimeoutMs
51694
+ );
51638
51695
  setPicker2({
51639
51696
  kind: "clarification",
51640
51697
  title: req.question,
@@ -52344,12 +52401,28 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
52344
52401
  Date.now()
52345
52402
  );
52346
52403
  let settled = false;
52404
+ const askTimeoutMs = askUserTimeoutMs();
52405
+ let cancelAskTimeout = () => void 0;
52347
52406
  const finish = (value) => {
52348
52407
  if (settled) return;
52349
52408
  settled = true;
52409
+ cancelAskTimeout();
52350
52410
  setPicker2(null);
52351
52411
  resolve3(value);
52352
52412
  };
52413
+ cancelAskTimeout = armPickerTimeout(
52414
+ () => {
52415
+ appendSystem(
52416
+ setMessages,
52417
+ `[council ask_user] nessuna risposta entro ${Math.round(
52418
+ askTimeoutMs / 1e3
52419
+ )}s \u2014 il membro prosegue con assunzione documentata (ZELARI_ASK_USER_TIMEOUT_MS).`,
52420
+ Date.now()
52421
+ );
52422
+ finish(null);
52423
+ },
52424
+ askTimeoutMs
52425
+ );
52353
52426
  setPicker2({
52354
52427
  kind: "clarification",
52355
52428
  title: req.question,
@@ -53114,12 +53187,25 @@ function usePermissionBroker(opts) {
53114
53187
  return;
53115
53188
  }
53116
53189
  let settled = false;
53190
+ let cancelWaitTimeout;
53117
53191
  const finish = (value) => {
53118
53192
  if (settled) return;
53119
53193
  settled = true;
53194
+ cancelWaitTimeout?.();
53120
53195
  setPicker2(null);
53121
53196
  resolve3(value);
53122
53197
  };
53198
+ const waitTimeoutMs = askUserTimeoutMs();
53199
+ cancelWaitTimeout = armPickerTimeout(() => {
53200
+ appendSystem(
53201
+ setMessages,
53202
+ `[external agent] nessuna risposta entro ${Math.round(
53203
+ waitTimeoutMs / 1e3
53204
+ )}s \u2014 richiesta annullata.`,
53205
+ Date.now()
53206
+ );
53207
+ finish(null);
53208
+ }, waitTimeoutMs);
53123
53209
  appendSystem(
53124
53210
  setMessages,
53125
53211
  `[external agent] ${req.question}
@@ -56395,6 +56481,11 @@ function App() {
56395
56481
  const [mode, setMode] = useState8("kraken");
56396
56482
  const [phase2, setPhaseUi] = useState8("build");
56397
56483
  const [picker, setPicker2] = useState8(null);
56484
+ const [pickerSince, setPickerSince] = useState8(0);
56485
+ useEffect8(() => {
56486
+ if (picker) setPickerSince((s) => s > 0 ? s : Date.now());
56487
+ else setPickerSince(0);
56488
+ }, [picker]);
56398
56489
  const activeProviderSpec = getActiveProvider();
56399
56490
  const activeModel = providerConfig.modelByProvider[activeProviderSpec.id];
56400
56491
  const session = useSession();
@@ -56519,7 +56610,16 @@ function App() {
56519
56610
  columns: size.columns || 80,
56520
56611
  rows: size.rows || 24
56521
56612
  }
56522
- ) : renderMessage(item)), /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "row" }, /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", flexGrow: 1, paddingX: 1 }, /* @__PURE__ */ React10.createElement(LiveRegion, { live: session.live, busy, elapsedMs: timer.elapsedMs }), picker ? /* @__PURE__ */ React10.createElement(
56613
+ ) : renderMessage(item)), /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "row" }, /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", flexGrow: 1, paddingX: 1 }, /* @__PURE__ */ React10.createElement(
56614
+ LiveRegion,
56615
+ {
56616
+ live: session.live,
56617
+ busy,
56618
+ elapsedMs: timer.elapsedMs,
56619
+ waitingForUser: picker !== null,
56620
+ waitingSinceMs: pickerSince
56621
+ }
56622
+ ), picker ? /* @__PURE__ */ React10.createElement(
56523
56623
  SelectList,
56524
56624
  {
56525
56625
  title: picker.title,