omnius 1.0.85 → 1.0.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -607760,10 +607760,10 @@ function decodeHelpCallback(data) {
607760
607760
  if (parts.length < 3) return null;
607761
607761
  const action = parts[1];
607762
607762
  const value2 = parts.slice(2).join(":");
607763
- if (action !== "page" && action !== "detail" && action !== "back") return null;
607763
+ if (action !== "page" && action !== "detail" && action !== "back" && action !== "close") return null;
607764
607764
  return { action, value: value2 };
607765
607765
  }
607766
- function buildToolListKeyboard(tools, page2, scope) {
607766
+ function buildToolListKeyboard(tools, page2, scope, countdown = null) {
607767
607767
  const totalPages = Math.max(1, Math.ceil(tools.length / TOOLS_PER_PAGE));
607768
607768
  const start2 = page2 * TOOLS_PER_PAGE;
607769
607769
  const pageTools = tools.slice(start2, start2 + TOOLS_PER_PAGE);
@@ -607784,6 +607784,10 @@ function buildToolListKeyboard(tools, page2, scope) {
607784
607784
  rows.push(currentRow);
607785
607785
  }
607786
607786
  const navRow = [];
607787
+ if (page2 === 0) {
607788
+ const closeLabel = countdown != null ? `✖ ${countdown}` : "✖ Close";
607789
+ navRow.push({ text: closeLabel, callback_data: encodeHelpCallback("close", "0") });
607790
+ }
607787
607791
  if (page2 > 0) {
607788
607792
  navRow.push({ text: "◀️ Back", callback_data: encodeHelpCallback("page", page2 - 1) });
607789
607793
  }
@@ -607873,6 +607877,14 @@ function renderHelpMenuPage(scope, page2) {
607873
607877
  const inline_keyboard = buildToolListKeyboard(tools, page2, scope);
607874
607878
  return { text, replyMarkup: { inline_keyboard } };
607875
607879
  }
607880
+ function renderHelpMenuPageWithCountdown(scope, page2, countdown) {
607881
+ const tools = buildScopedToolList(scope);
607882
+ const totalPages = Math.max(1, Math.ceil(tools.length / TOOLS_PER_PAGE));
607883
+ page2 = Math.max(0, Math.min(page2, totalPages - 1));
607884
+ const text = buildToolListText(tools, page2, scope);
607885
+ const inline_keyboard = buildToolListKeyboard(tools, page2, scope, countdown);
607886
+ return { text, replyMarkup: { inline_keyboard } };
607887
+ }
607876
607888
  function renderHelpToolDetail(scope, toolName, returnPage) {
607877
607889
  const tools = buildScopedToolList(scope);
607878
607890
  const tool = tools.find((t2) => t2.name === toolName);
@@ -607892,29 +607904,32 @@ function handleHelpCallback(callbackData, currentState) {
607892
607904
  const page2 = parseInt(value2, 10);
607893
607905
  if (isNaN(page2)) return null;
607894
607906
  render2 = renderHelpMenuPage(currentState.scope, page2);
607895
- newState = { ...currentState, page: page2, view: "list", detailToolName: null };
607907
+ newState = { ...currentState, page: page2, view: "list", detailToolName: null, lastInteractionAt: Date.now() };
607896
607908
  break;
607897
607909
  }
607898
607910
  case "detail": {
607899
607911
  const detail = renderHelpToolDetail(currentState.scope, value2, currentState.page);
607900
607912
  if (!detail) return null;
607901
607913
  render2 = detail;
607902
- newState = { ...currentState, view: "detail", detailToolName: value2 };
607914
+ newState = { ...currentState, view: "detail", detailToolName: value2, lastInteractionAt: Date.now() };
607903
607915
  break;
607904
607916
  }
607905
607917
  case "back": {
607906
607918
  const page2 = parseInt(value2, 10);
607907
607919
  if (isNaN(page2)) return null;
607908
607920
  render2 = renderHelpMenuPage(currentState.scope, page2);
607909
- newState = { ...currentState, page: page2, view: "list", detailToolName: null };
607921
+ newState = { ...currentState, page: page2, view: "list", detailToolName: null, lastInteractionAt: Date.now() };
607910
607922
  break;
607911
607923
  }
607924
+ case "close": {
607925
+ return { render: null, newState: currentState, close: true };
607926
+ }
607912
607927
  default:
607913
607928
  return null;
607914
607929
  }
607915
607930
  return { render: render2, newState };
607916
607931
  }
607917
- var TOOLS_PER_PAGE, GRID_COLS, CALLBACK_PREFIX, MAX_CALLBACK_DATA, TELEGRAM_PUBLIC_HELP_COMMANDS, HelpMenuStateStore;
607932
+ var TOOLS_PER_PAGE, GRID_COLS, CALLBACK_PREFIX, MAX_CALLBACK_DATA, INACTIVITY_TIMEOUT_MS, COUNTDOWN_SECONDS, TELEGRAM_PUBLIC_HELP_COMMANDS, HelpMenuStateStore, HelpMenuTimerManager;
607918
607933
  var init_telegram_help_menu = __esm({
607919
607934
  "packages/cli/src/tui/telegram-help-menu.ts"() {
607920
607935
  "use strict";
@@ -607923,6 +607938,8 @@ var init_telegram_help_menu = __esm({
607923
607938
  GRID_COLS = 5;
607924
607939
  CALLBACK_PREFIX = "help";
607925
607940
  MAX_CALLBACK_DATA = 64;
607941
+ INACTIVITY_TIMEOUT_MS = 6e4;
607942
+ COUNTDOWN_SECONDS = 10;
607926
607943
  TELEGRAM_PUBLIC_HELP_COMMANDS = /* @__PURE__ */ new Set(["help", "start", "auth", "call"]);
607927
607944
  HelpMenuStateStore = class {
607928
607945
  states = /* @__PURE__ */ new Map();
@@ -607948,6 +607965,116 @@ var init_telegram_help_menu = __esm({
607948
607965
  }
607949
607966
  }
607950
607967
  };
607968
+ HelpMenuTimerManager = class {
607969
+ inactivityTimers = /* @__PURE__ */ new Map();
607970
+ countdownIntervals = /* @__PURE__ */ new Map();
607971
+ stateStore;
607972
+ callbacks;
607973
+ constructor(stateStore, callbacks) {
607974
+ this.stateStore = stateStore;
607975
+ this.callbacks = callbacks;
607976
+ }
607977
+ key(chatId, messageId) {
607978
+ return `${chatId}:${messageId}`;
607979
+ }
607980
+ /** Start the inactivity timer for a newly created menu */
607981
+ startTimer(state) {
607982
+ this.clearTimer(state.chatId, state.messageId);
607983
+ const k = this.key(state.chatId, state.messageId);
607984
+ const timer = setTimeout(() => {
607985
+ this.inactivityTimers.delete(k);
607986
+ this.startCountdown(state);
607987
+ }, INACTIVITY_TIMEOUT_MS);
607988
+ this.inactivityTimers.set(k, timer);
607989
+ }
607990
+ /** Reset the inactivity timer after user interaction */
607991
+ resetTimer(chatId, messageId) {
607992
+ const state = this.stateStore.get(chatId, messageId);
607993
+ if (!state) return;
607994
+ this.cancelCountdown(chatId, messageId);
607995
+ const updated = { ...state, lastInteractionAt: Date.now(), countdownValue: null };
607996
+ this.stateStore.set(updated);
607997
+ this.startTimer(updated);
607998
+ }
607999
+ /** Clear all timers for a menu (used when menu is closed or deleted) */
608000
+ clearTimer(chatId, messageId) {
608001
+ const k = this.key(chatId, messageId);
608002
+ const timer = this.inactivityTimers.get(k);
608003
+ if (timer) {
608004
+ clearTimeout(timer);
608005
+ this.inactivityTimers.delete(k);
608006
+ }
608007
+ this.cancelCountdown(chatId, messageId);
608008
+ }
608009
+ /** Start the 10-second countdown, updating the close button each second */
608010
+ startCountdown(state) {
608011
+ const k = this.key(state.chatId, state.messageId);
608012
+ let countdown = COUNTDOWN_SECONDS;
608013
+ const updatedState = { ...state, countdownValue: countdown, lastInteractionAt: Date.now() };
608014
+ this.stateStore.set(updatedState);
608015
+ this.updateCountdownButton(updatedState);
608016
+ const interval = setInterval(() => {
608017
+ countdown--;
608018
+ if (countdown <= 0) {
608019
+ clearInterval(interval);
608020
+ this.countdownIntervals.delete(k);
608021
+ this.deleteMenu(state.chatId, state.messageId);
608022
+ } else {
608023
+ const s2 = { ...state, countdownValue: countdown, lastInteractionAt: Date.now() };
608024
+ this.stateStore.set(s2);
608025
+ this.updateCountdownButton(s2);
608026
+ }
608027
+ }, 1e3);
608028
+ this.countdownIntervals.set(k, interval);
608029
+ }
608030
+ cancelCountdown(chatId, messageId) {
608031
+ const k = this.key(chatId, messageId);
608032
+ const interval = this.countdownIntervals.get(k);
608033
+ if (interval) {
608034
+ clearInterval(interval);
608035
+ this.countdownIntervals.delete(k);
608036
+ }
608037
+ }
608038
+ /** Update the close button to show countdown value */
608039
+ async updateCountdownButton(state) {
608040
+ try {
608041
+ let render2;
608042
+ if (state.view === "list") {
608043
+ render2 = renderHelpMenuPageWithCountdown(state.scope, state.page, state.countdownValue);
608044
+ } else {
608045
+ render2 = renderHelpToolDetail(state.scope, state.detailToolName, state.page);
608046
+ }
608047
+ if (!render2) return;
608048
+ await this.callbacks.editMessageText(
608049
+ state.chatId,
608050
+ state.messageId,
608051
+ render2.text,
608052
+ render2.replyMarkup
608053
+ );
608054
+ } catch {
608055
+ }
608056
+ }
608057
+ /** Delete the menu message and clean up state */
608058
+ async deleteMenu(chatId, messageId) {
608059
+ this.clearTimer(chatId, messageId);
608060
+ this.stateStore.delete(chatId, messageId);
608061
+ try {
608062
+ await this.callbacks.deleteMessage(chatId, messageId);
608063
+ } catch {
608064
+ }
608065
+ }
608066
+ /** Clean up all timers (for shutdown) */
608067
+ destroyAll() {
608068
+ for (const [k, timer] of this.inactivityTimers) {
608069
+ clearTimeout(timer);
608070
+ }
608071
+ this.inactivityTimers.clear();
608072
+ for (const [k, interval] of this.countdownIntervals) {
608073
+ clearInterval(interval);
608074
+ }
608075
+ this.countdownIntervals.clear();
608076
+ }
608077
+ };
607951
608078
  }
607952
608079
  });
607953
608080
 
@@ -612830,6 +612957,8 @@ External acquisition contract:
612830
612957
  telegramToolButtonDir;
612831
612958
  /** Interactive help menu state store (inline keyboard navigation) */
612832
612959
  helpMenuStates = new HelpMenuStateStore();
612960
+ /** Auto-close timer manager for help menus (inactivity → countdown → delete) */
612961
+ helpMenuTimers = null;
612833
612962
  /** Prune expired help menu states every 5 minutes */
612834
612963
  helpMenuPruneTimer = null;
612835
612964
  /** Command handler for admin DM slash commands (wired from interactive.ts) */
@@ -613267,7 +613396,7 @@ No scoped reflection artifact exists yet for this chat. Use <code>/reflect</code
613267
613396
  ...msg.chatType !== "private" ? { reply_to_message_id: msg.messageId } : {}
613268
613397
  });
613269
613398
  if (sent.ok && sent.result?.message_id) {
613270
- this.helpMenuStates.set({
613399
+ const state = {
613271
613400
  chatId: msg.chatId,
613272
613401
  messageId: sent.result.message_id,
613273
613402
  scope,
@@ -613275,8 +613404,31 @@ No scoped reflection artifact exists yet for this chat. Use <code>/reflect</code
613275
613404
  view: "list",
613276
613405
  detailToolName: null,
613277
613406
  fromUserId: msg.fromUserId ?? 0,
613278
- createdAt: Date.now()
613279
- });
613407
+ createdAt: Date.now(),
613408
+ lastInteractionAt: Date.now(),
613409
+ countdownValue: null
613410
+ };
613411
+ this.helpMenuStates.set(state);
613412
+ if (!this.helpMenuTimers) {
613413
+ this.helpMenuTimers = new HelpMenuTimerManager(this.helpMenuStates, {
613414
+ editMessageText: async (chatId, messageId, text, replyMarkup) => {
613415
+ await this.apiCall("editMessageText", {
613416
+ chat_id: chatId,
613417
+ message_id: messageId,
613418
+ text,
613419
+ parse_mode: "HTML",
613420
+ reply_markup: JSON.stringify(replyMarkup)
613421
+ });
613422
+ },
613423
+ deleteMessage: async (chatId, messageId) => {
613424
+ await this.apiCall("deleteMessage", {
613425
+ chat_id: chatId,
613426
+ message_id: messageId
613427
+ });
613428
+ }
613429
+ });
613430
+ }
613431
+ this.helpMenuTimers.startTimer(state);
613280
613432
  }
613281
613433
  }
613282
613434
  recordChatHistory(sessionKey, entry) {
@@ -619619,7 +619771,21 @@ Scoped workspace: ${scopedRoot}`,
619619
619771
  alert2 = true;
619620
619772
  return;
619621
619773
  }
619774
+ if (result.close) {
619775
+ this.helpMenuStates.delete(chatId, messageId);
619776
+ this.helpMenuTimers?.deleteMenu(chatId, messageId);
619777
+ try {
619778
+ await this.apiCall("deleteMessage", {
619779
+ chat_id: chatId,
619780
+ message_id: messageId
619781
+ });
619782
+ } catch {
619783
+ }
619784
+ await this.answerCallbackQuery(callback.id).catch(() => false);
619785
+ return;
619786
+ }
619622
619787
  this.helpMenuStates.set(result.newState);
619788
+ this.helpMenuTimers?.resetTimer(chatId, messageId);
619623
619789
  await this.apiCall("editMessageText", {
619624
619790
  chat_id: chatId,
619625
619791
  message_id: messageId,
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.85",
3
+ "version": "1.0.86",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.85",
9
+ "version": "1.0.86",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.85",
3
+ "version": "1.0.86",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",