openhorse 0.1.19 → 0.1.21

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 (84) hide show
  1. package/dist/cli.js +446 -33
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/index.d.ts.map +1 -1
  4. package/dist/commands/index.js +99 -40
  5. package/dist/commands/index.js.map +1 -1
  6. package/dist/commands/types.d.ts +14 -0
  7. package/dist/commands/types.d.ts.map +1 -1
  8. package/dist/commands/types.js.map +1 -1
  9. package/dist/framework/query.d.ts.map +1 -1
  10. package/dist/framework/query.js +25 -7
  11. package/dist/framework/query.js.map +1 -1
  12. package/dist/runtime/turn-controller.d.ts +37 -0
  13. package/dist/runtime/turn-controller.d.ts.map +1 -0
  14. package/dist/runtime/turn-controller.js +84 -0
  15. package/dist/runtime/turn-controller.js.map +1 -0
  16. package/dist/services/config.d.ts +4 -2
  17. package/dist/services/config.d.ts.map +1 -1
  18. package/dist/services/config.js +30 -0
  19. package/dist/services/config.js.map +1 -1
  20. package/dist/services/global-config.d.ts +13 -0
  21. package/dist/services/global-config.d.ts.map +1 -1
  22. package/dist/services/global-config.js +4 -0
  23. package/dist/services/global-config.js.map +1 -1
  24. package/dist/services/llm.d.ts +4 -1
  25. package/dist/services/llm.d.ts.map +1 -1
  26. package/dist/services/llm.js +15 -2
  27. package/dist/services/llm.js.map +1 -1
  28. package/dist/ui/command-panel.d.ts +17 -0
  29. package/dist/ui/command-panel.d.ts.map +1 -1
  30. package/dist/ui/command-panel.js +234 -93
  31. package/dist/ui/command-panel.js.map +1 -1
  32. package/dist/ui/file-completion.d.ts +3 -0
  33. package/dist/ui/file-completion.d.ts.map +1 -1
  34. package/dist/ui/file-completion.js +7 -2
  35. package/dist/ui/file-completion.js.map +1 -1
  36. package/dist/ui/multiline-input.d.ts +4 -0
  37. package/dist/ui/multiline-input.d.ts.map +1 -1
  38. package/dist/ui/multiline-input.js +7 -0
  39. package/dist/ui/multiline-input.js.map +1 -1
  40. package/dist/ui/user-input.d.ts +1 -0
  41. package/dist/ui/user-input.d.ts.map +1 -1
  42. package/dist/ui/user-input.js +8 -4
  43. package/dist/ui/user-input.js.map +1 -1
  44. package/dist/ui-v2/components/command-palette.d.ts +6 -0
  45. package/dist/ui-v2/components/command-palette.d.ts.map +1 -0
  46. package/dist/ui-v2/components/command-palette.js +57 -0
  47. package/dist/ui-v2/components/command-palette.js.map +1 -0
  48. package/dist/ui-v2/components/session-picker.d.ts +17 -0
  49. package/dist/ui-v2/components/session-picker.d.ts.map +1 -0
  50. package/dist/ui-v2/components/session-picker.js +23 -0
  51. package/dist/ui-v2/components/session-picker.js.map +1 -0
  52. package/dist/ui-v2/components/shell.d.ts +49 -0
  53. package/dist/ui-v2/components/shell.d.ts.map +1 -0
  54. package/dist/ui-v2/components/shell.js +190 -0
  55. package/dist/ui-v2/components/shell.js.map +1 -0
  56. package/dist/ui-v2/index.d.ts +10 -0
  57. package/dist/ui-v2/index.d.ts.map +1 -0
  58. package/dist/ui-v2/index.js +26 -0
  59. package/dist/ui-v2/index.js.map +1 -0
  60. package/dist/ui-v2/runtime/text.d.ts +8 -0
  61. package/dist/ui-v2/runtime/text.d.ts.map +1 -0
  62. package/dist/ui-v2/runtime/text.js +58 -0
  63. package/dist/ui-v2/runtime/text.js.map +1 -0
  64. package/dist/ui-v2/state/input-reducer.d.ts +39 -0
  65. package/dist/ui-v2/state/input-reducer.d.ts.map +1 -0
  66. package/dist/ui-v2/state/input-reducer.js +82 -0
  67. package/dist/ui-v2/state/input-reducer.js.map +1 -0
  68. package/dist/ui-v2/state/picker.d.ts +16 -0
  69. package/dist/ui-v2/state/picker.d.ts.map +1 -0
  70. package/dist/ui-v2/state/picker.js +52 -0
  71. package/dist/ui-v2/state/picker.js.map +1 -0
  72. package/dist/ui-v2/state/sessions.d.ts +14 -0
  73. package/dist/ui-v2/state/sessions.d.ts.map +1 -0
  74. package/dist/ui-v2/state/sessions.js +65 -0
  75. package/dist/ui-v2/state/sessions.js.map +1 -0
  76. package/dist/ui-v2/state/suggestions.d.ts +22 -0
  77. package/dist/ui-v2/state/suggestions.d.ts.map +1 -0
  78. package/dist/ui-v2/state/suggestions.js +55 -0
  79. package/dist/ui-v2/state/suggestions.js.map +1 -0
  80. package/dist/ui-v2/types.d.ts +33 -0
  81. package/dist/ui-v2/types.d.ts.map +1 -0
  82. package/dist/ui-v2/types.js +9 -0
  83. package/dist/ui-v2/types.js.map +1 -0
  84. package/package.json +2 -2
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ /**
3
+ * Prompt input reducer for UI v2.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.initialInputState = void 0;
7
+ exports.reduceInput = reduceInput;
8
+ exports.initialInputState = {
9
+ value: '',
10
+ cursor: 0,
11
+ multiline: false,
12
+ historyIndex: null,
13
+ searchQuery: null,
14
+ };
15
+ function reduceInput(state, action) {
16
+ switch (action.type) {
17
+ case 'insert': {
18
+ if (!action.text)
19
+ return state;
20
+ const cursor = clampCursor(state.cursor, state.value);
21
+ const value = state.value.slice(0, cursor) + action.text + state.value.slice(cursor);
22
+ return {
23
+ ...state,
24
+ value,
25
+ cursor: cursor + action.text.length,
26
+ historyIndex: null,
27
+ };
28
+ }
29
+ case 'backspace': {
30
+ const cursor = clampCursor(state.cursor, state.value);
31
+ if (cursor === 0)
32
+ return state;
33
+ const value = state.value.slice(0, cursor - 1) + state.value.slice(cursor);
34
+ return { ...state, value, cursor: cursor - 1, historyIndex: null };
35
+ }
36
+ case 'delete': {
37
+ const cursor = clampCursor(state.cursor, state.value);
38
+ if (cursor >= state.value.length)
39
+ return state;
40
+ const value = state.value.slice(0, cursor) + state.value.slice(cursor + 1);
41
+ return { ...state, value, cursor, historyIndex: null };
42
+ }
43
+ case 'move': {
44
+ return { ...state, cursor: moveCursor(state.value, state.cursor, action.direction) };
45
+ }
46
+ case 'set': {
47
+ const cursor = action.cursor ?? action.value.length;
48
+ return {
49
+ ...state,
50
+ value: action.value,
51
+ cursor: clampCursor(cursor, action.value),
52
+ };
53
+ }
54
+ case 'clear':
55
+ return { ...exports.initialInputState };
56
+ case 'setMultiline':
57
+ return { ...state, multiline: action.multiline };
58
+ case 'setHistoryIndex':
59
+ return { ...state, historyIndex: action.historyIndex };
60
+ case 'setSearchQuery':
61
+ return { ...state, searchQuery: action.searchQuery };
62
+ }
63
+ }
64
+ function moveCursor(value, cursor, direction) {
65
+ const current = clampCursor(cursor, value);
66
+ switch (direction) {
67
+ case 'left':
68
+ return Math.max(0, current - 1);
69
+ case 'right':
70
+ return Math.min(value.length, current + 1);
71
+ case 'home':
72
+ return 0;
73
+ case 'end':
74
+ return value.length;
75
+ }
76
+ }
77
+ function clampCursor(cursor, value) {
78
+ if (!Number.isFinite(cursor))
79
+ return value.length;
80
+ return Math.min(Math.max(0, Math.floor(cursor)), value.length);
81
+ }
82
+ //# sourceMappingURL=input-reducer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-reducer.js","sourceRoot":"","sources":["../../../src/ui-v2/state/input-reducer.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AA6BH,kCAqDC;AA7DY,QAAA,iBAAiB,GAAe;IAC3C,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,KAAK;IAChB,YAAY,EAAE,IAAI;IAClB,WAAW,EAAE,IAAI;CAClB,CAAC;AAEF,SAAgB,WAAW,CAAC,KAAiB,EAAE,MAAmB;IAChE,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,IAAI;gBAAE,OAAO,KAAK,CAAC;YAC/B,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YACtD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACrF,OAAO;gBACL,GAAG,KAAK;gBACR,KAAK;gBACL,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM;gBACnC,YAAY,EAAE,IAAI;aACnB,CAAC;QACJ,CAAC;QAED,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YACtD,IAAI,MAAM,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3E,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QACrE,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YACtD,IAAI,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM;gBAAE,OAAO,KAAK,CAAC;YAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC3E,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QACzD,CAAC;QAED,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,OAAO,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QACvF,CAAC;QAED,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;YACpD,OAAO;gBACL,GAAG,KAAK;gBACR,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC;aAC1C,CAAC;QACJ,CAAC;QAED,KAAK,OAAO;YACV,OAAO,EAAE,GAAG,yBAAiB,EAAE,CAAC;QAElC,KAAK,cAAc;YACjB,OAAO,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;QAEnD,KAAK,iBAAiB;YACpB,OAAO,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;QAEzD,KAAK,gBAAgB;YACnB,OAAO,EAAE,GAAG,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;IACzD,CAAC;AACH,CAAC;AAID,SAAS,UAAU,CAAC,KAAa,EAAE,MAAc,EAAE,SAAwB;IACzE,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC3C,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;QAClC,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;QAC7C,KAAK,MAAM;YACT,OAAO,CAAC,CAAC;QACX,KAAK,KAAK;YACR,OAAO,KAAK,CAAC,MAAM,CAAC;IACxB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,MAAc,EAAE,KAAa;IAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC,MAAM,CAAC;IAClD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Generic picker state reducer for UI v2 overlays.
3
+ */
4
+ import type { SuggestionItem } from '../types';
5
+ export interface PickerState {
6
+ visible: boolean;
7
+ query: string;
8
+ selectedIndex: number;
9
+ items: SuggestionItem[];
10
+ }
11
+ export declare function createPickerState(items?: SuggestionItem[], query?: string, visible?: boolean): PickerState;
12
+ export declare function updatePickerItems(state: PickerState, items: SuggestionItem[], query?: string): PickerState;
13
+ export declare function closePicker(state: PickerState): PickerState;
14
+ export declare function movePickerSelection(state: PickerState, direction: 'up' | 'down'): PickerState;
15
+ export declare function getSelectedPickerItem(state: PickerState): SuggestionItem | null;
16
+ //# sourceMappingURL=picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker.d.ts","sourceRoot":"","sources":["../../../src/ui-v2/state/picker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,GAAE,cAAc,EAAO,EAAE,KAAK,GAAE,MAAW,EAAE,OAAO,GAAE,OAA0B,GAAG,WAAW,CAOpI;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,KAAK,GAAE,MAAoB,GAAG,WAAW,CAOvH;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAM3D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,CAQ7F;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,cAAc,GAAG,IAAI,CAG/E"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ /**
3
+ * Generic picker state reducer for UI v2 overlays.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createPickerState = createPickerState;
7
+ exports.updatePickerItems = updatePickerItems;
8
+ exports.closePicker = closePicker;
9
+ exports.movePickerSelection = movePickerSelection;
10
+ exports.getSelectedPickerItem = getSelectedPickerItem;
11
+ function createPickerState(items = [], query = '', visible = items.length > 0) {
12
+ return {
13
+ visible,
14
+ query,
15
+ selectedIndex: 0,
16
+ items,
17
+ };
18
+ }
19
+ function updatePickerItems(state, items, query = state.query) {
20
+ return {
21
+ visible: state.visible,
22
+ query,
23
+ selectedIndex: clampIndex(state.selectedIndex, items.length),
24
+ items,
25
+ };
26
+ }
27
+ function closePicker(state) {
28
+ return {
29
+ ...state,
30
+ visible: false,
31
+ selectedIndex: 0,
32
+ };
33
+ }
34
+ function movePickerSelection(state, direction) {
35
+ if (!state.visible || state.items.length === 0)
36
+ return state;
37
+ const nextIndex = direction === 'up'
38
+ ? Math.max(0, state.selectedIndex - 1)
39
+ : Math.min(state.items.length - 1, state.selectedIndex + 1);
40
+ return { ...state, selectedIndex: nextIndex };
41
+ }
42
+ function getSelectedPickerItem(state) {
43
+ if (!state.visible || state.items.length === 0)
44
+ return null;
45
+ return state.items[state.selectedIndex] ?? null;
46
+ }
47
+ function clampIndex(index, itemCount) {
48
+ if (itemCount <= 0)
49
+ return 0;
50
+ return Math.min(Math.max(index, 0), itemCount - 1);
51
+ }
52
+ //# sourceMappingURL=picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker.js","sourceRoot":"","sources":["../../../src/ui-v2/state/picker.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAWH,8CAOC;AAED,8CAOC;AAED,kCAMC;AAED,kDAQC;AAED,sDAGC;AAvCD,SAAgB,iBAAiB,CAAC,QAA0B,EAAE,EAAE,QAAgB,EAAE,EAAE,UAAmB,KAAK,CAAC,MAAM,GAAG,CAAC;IACrH,OAAO;QACL,OAAO;QACP,KAAK;QACL,aAAa,EAAE,CAAC;QAChB,KAAK;KACN,CAAC;AACJ,CAAC;AAED,SAAgB,iBAAiB,CAAC,KAAkB,EAAE,KAAuB,EAAE,QAAgB,KAAK,CAAC,KAAK;IACxG,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK;QACL,aAAa,EAAE,UAAU,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC;QAC5D,KAAK;KACN,CAAC;AACJ,CAAC;AAED,SAAgB,WAAW,CAAC,KAAkB;IAC5C,OAAO;QACL,GAAG,KAAK;QACR,OAAO,EAAE,KAAK;QACd,aAAa,EAAE,CAAC;KACjB,CAAC;AACJ,CAAC;AAED,SAAgB,mBAAmB,CAAC,KAAkB,EAAE,SAAwB;IAC9E,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE7D,MAAM,SAAS,GAAG,SAAS,KAAK,IAAI;QAClC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC;QACtC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;IAE9D,OAAO,EAAE,GAAG,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AAChD,CAAC;AAED,SAAgB,qBAAqB,CAAC,KAAkB;IACtD,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5D,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC;AAClD,CAAC;AAED,SAAS,UAAU,CAAC,KAAa,EAAE,SAAiB;IAClD,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC7B,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * UI v2 session suggestion builders.
3
+ */
4
+ import type { SessionMeta } from '../../services/session-storage';
5
+ import type { SuggestionItem } from '../types';
6
+ export interface BuildSessionSuggestionsOptions {
7
+ showProject?: boolean;
8
+ now?: number;
9
+ }
10
+ export declare function buildSessionSuggestions(sessions: SessionMeta[], options?: BuildSessionSuggestionsOptions): SuggestionItem[];
11
+ export declare function sessionToSuggestion(session: SessionMeta, index: number, options?: BuildSessionSuggestionsOptions): SuggestionItem;
12
+ export declare function sessionDisplayTitle(session: SessionMeta): string;
13
+ export declare function formatRelativeTime(timestamp: number, now?: number): string;
14
+ //# sourceMappingURL=sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/ui-v2/state/sessions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,WAAW,8BAA8B;IAC7C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,WAAW,EAAE,EACvB,OAAO,GAAE,8BAAmC,GAC3C,cAAc,EAAE,CAElB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,8BAAmC,GAC3C,cAAc,CA6BhB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAEhE;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,CAmBtF"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ /**
3
+ * UI v2 session suggestion builders.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildSessionSuggestions = buildSessionSuggestions;
7
+ exports.sessionToSuggestion = sessionToSuggestion;
8
+ exports.sessionDisplayTitle = sessionDisplayTitle;
9
+ exports.formatRelativeTime = formatRelativeTime;
10
+ const path_1 = require("path");
11
+ function buildSessionSuggestions(sessions, options = {}) {
12
+ return sessions.map((session, index) => sessionToSuggestion(session, index, options));
13
+ }
14
+ function sessionToSuggestion(session, index, options = {}) {
15
+ const shortId = session.id.slice(0, 8);
16
+ const title = sessionDisplayTitle(session);
17
+ const updatedAt = session.updatedAt ?? session.startTime;
18
+ const detailParts = [
19
+ shortId,
20
+ session.model,
21
+ `${session.messageCount ?? 0} msg`,
22
+ formatRelativeTime(updatedAt, options.now ?? Date.now()),
23
+ ];
24
+ if (options.showProject && session.projectPath) {
25
+ detailParts.push((0, path_1.basename)(session.projectPath) || session.projectPath);
26
+ }
27
+ return {
28
+ id: `session:${session.id}`,
29
+ kind: 'session',
30
+ label: `#${index + 1} ${title}`,
31
+ detail: detailParts.join(' '),
32
+ value: session.id,
33
+ metadata: {
34
+ index: index + 1,
35
+ sessionId: session.id,
36
+ projectPath: session.projectPath,
37
+ updatedAt,
38
+ messageCount: session.messageCount ?? 0,
39
+ },
40
+ };
41
+ }
42
+ function sessionDisplayTitle(session) {
43
+ return session.name || session.taskSummary || '(untitled)';
44
+ }
45
+ function formatRelativeTime(timestamp, now = Date.now()) {
46
+ const diffMs = Math.max(0, now - timestamp);
47
+ const seconds = Math.floor(diffMs / 1000);
48
+ if (seconds < 60)
49
+ return 'now';
50
+ const minutes = Math.floor(seconds / 60);
51
+ if (minutes < 60)
52
+ return `${minutes}m ago`;
53
+ const hours = Math.floor(minutes / 60);
54
+ if (hours < 24)
55
+ return `${hours}h ago`;
56
+ const days = Math.floor(hours / 24);
57
+ if (days < 30)
58
+ return `${days}d ago`;
59
+ const months = Math.floor(days / 30);
60
+ if (months < 12)
61
+ return `${months}mo ago`;
62
+ const years = Math.floor(months / 12);
63
+ return `${years}y ago`;
64
+ }
65
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../src/ui-v2/state/sessions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * UI v2 suggestion builders.
3
+ */
4
+ import type { SlashCommand } from '../../commands/types';
5
+ import type { SuggestionItem } from '../types';
6
+ export declare const DEFAULT_COMMAND_LIMIT = 8;
7
+ export declare const FILTERED_COMMAND_LIMIT = 6;
8
+ export interface CommandSuggestionResult {
9
+ query: string;
10
+ total: number;
11
+ limit: number;
12
+ moreCount: number;
13
+ items: SuggestionItem[];
14
+ commands: SlashCommand[];
15
+ }
16
+ export interface BuildCommandSuggestionsOptions {
17
+ defaultLimit?: number;
18
+ filteredLimit?: number;
19
+ }
20
+ export declare function buildCommandSuggestions(commands: SlashCommand[], query?: string, options?: BuildCommandSuggestionsOptions): CommandSuggestionResult;
21
+ export declare function commandToSuggestion(command: SlashCommand): SuggestionItem;
22
+ //# sourceMappingURL=suggestions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestions.d.ts","sourceRoot":"","sources":["../../../src/ui-v2/state/suggestions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,8BAA8B;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,YAAY,EAAE,EACxB,KAAK,GAAE,MAAW,EAClB,OAAO,GAAE,8BAAmC,GAC3C,uBAAuB,CAoBzB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,cAAc,CAezE"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ /**
3
+ * UI v2 suggestion builders.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FILTERED_COMMAND_LIMIT = exports.DEFAULT_COMMAND_LIMIT = void 0;
7
+ exports.buildCommandSuggestions = buildCommandSuggestions;
8
+ exports.commandToSuggestion = commandToSuggestion;
9
+ exports.DEFAULT_COMMAND_LIMIT = 8;
10
+ exports.FILTERED_COMMAND_LIMIT = 6;
11
+ function buildCommandSuggestions(commands, query = '', options = {}) {
12
+ const normalizedQuery = normalizeQuery(query);
13
+ const defaultLimit = options.defaultLimit ?? exports.DEFAULT_COMMAND_LIMIT;
14
+ const filteredLimit = options.filteredLimit ?? exports.FILTERED_COMMAND_LIMIT;
15
+ const limit = normalizedQuery ? filteredLimit : defaultLimit;
16
+ const visibleCommands = commands.filter(cmd => !cmd.isHidden);
17
+ const matches = normalizedQuery
18
+ ? visibleCommands.filter(cmd => commandMatches(cmd, normalizedQuery))
19
+ : visibleCommands;
20
+ const limitedCommands = matches.slice(0, limit);
21
+ return {
22
+ query: normalizedQuery,
23
+ total: matches.length,
24
+ limit,
25
+ moreCount: Math.max(0, matches.length - limitedCommands.length),
26
+ items: limitedCommands.map(commandToSuggestion),
27
+ commands: limitedCommands,
28
+ };
29
+ }
30
+ function commandToSuggestion(command) {
31
+ const shortcut = command.aliases?.[0];
32
+ return {
33
+ id: `command:${command.name}`,
34
+ kind: 'command',
35
+ label: `/${command.name}`,
36
+ detail: command.description,
37
+ shortcut,
38
+ value: `/${command.name}`,
39
+ metadata: {
40
+ argumentHint: command.argumentHint,
41
+ type: command.type,
42
+ aliases: command.aliases ?? [],
43
+ },
44
+ };
45
+ }
46
+ function commandMatches(command, query) {
47
+ const name = command.name.toLowerCase();
48
+ if (name.startsWith(query))
49
+ return true;
50
+ return command.aliases?.some(alias => alias.toLowerCase().startsWith(query)) ?? false;
51
+ }
52
+ function normalizeQuery(query) {
53
+ return query.trim().replace(/^\//, '').toLowerCase();
54
+ }
55
+ //# sourceMappingURL=suggestions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestions.js","sourceRoot":"","sources":["../../../src/ui-v2/state/suggestions.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAsBH,0DAwBC;AAED,kDAeC;AA1DY,QAAA,qBAAqB,GAAG,CAAC,CAAC;AAC1B,QAAA,sBAAsB,GAAG,CAAC,CAAC;AAgBxC,SAAgB,uBAAuB,CACrC,QAAwB,EACxB,QAAgB,EAAE,EAClB,UAA0C,EAAE;IAE5C,MAAM,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,6BAAqB,CAAC;IACnE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,8BAAsB,CAAC;IACtE,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC;IAE7D,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,eAAe;QAC7B,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QACrE,CAAC,CAAC,eAAe,CAAC;IACpB,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEhD,OAAO;QACL,KAAK,EAAE,eAAe;QACtB,KAAK,EAAE,OAAO,CAAC,MAAM;QACrB,KAAK;QACL,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC;QAC/D,KAAK,EAAE,eAAe,CAAC,GAAG,CAAC,mBAAmB,CAAC;QAC/C,QAAQ,EAAE,eAAe;KAC1B,CAAC;AACJ,CAAC;AAED,SAAgB,mBAAmB,CAAC,OAAqB;IACvD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IACtC,OAAO;QACL,EAAE,EAAE,WAAW,OAAO,CAAC,IAAI,EAAE;QAC7B,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE;QACzB,MAAM,EAAE,OAAO,CAAC,WAAW;QAC3B,QAAQ;QACR,KAAK,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE;QACzB,QAAQ,EAAE;YACR,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;SAC/B;KACF,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,OAAqB,EAAE,KAAa;IAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC;AACxF,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AACvD,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * OpenHorse UI v2 shared types.
3
+ *
4
+ * The first v2 slice keeps rendering lightweight and state-driven so the
5
+ * legacy REPL can adopt it incrementally before a full Ink renderer lands.
6
+ */
7
+ export type SuggestionKind = 'command' | 'file' | 'session' | 'model' | 'mcp-resource' | 'skill';
8
+ export interface SuggestionItem {
9
+ id: string;
10
+ kind: SuggestionKind;
11
+ label: string;
12
+ detail?: string;
13
+ shortcut?: string;
14
+ disabledReason?: string;
15
+ value?: string;
16
+ metadata?: Record<string, unknown>;
17
+ }
18
+ export interface PaletteTheme {
19
+ accent: (text: string) => string;
20
+ dim: (text: string) => string;
21
+ selected: (text: string) => string;
22
+ }
23
+ export interface PaletteRenderOptions {
24
+ title: string;
25
+ items: SuggestionItem[];
26
+ selectedIndex: number;
27
+ width: number;
28
+ moreCount?: number;
29
+ footer?: string;
30
+ emptyLabel?: string;
31
+ theme: PaletteTheme;
32
+ }
33
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ui-v2/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,MAAM,GACN,SAAS,GACT,OAAO,GACP,cAAc,GACd,OAAO,CAAC;AAEZ,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACjC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;CACrB"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /**
3
+ * OpenHorse UI v2 shared types.
4
+ *
5
+ * The first v2 slice keeps rendering lightweight and state-driven so the
6
+ * legacy REPL can adopt it incrementally before a full Ink renderer lands.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ui-v2/types.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openhorse",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "OpenHorse - Universal Agent Harness Framework. A complete coding CLI agent with tools, MCP, memory system.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -21,7 +21,7 @@
21
21
  "test": "jest",
22
22
  "lint": "eslint src/",
23
23
  "format": "prettier --write src/",
24
- "prepublishOnly": "npm run build && npm test"
24
+ "prepublishOnly": "npm run build && npm test -- --runInBand"
25
25
  },
26
26
  "keywords": [
27
27
  "agent",