@positronic/cli 0.0.74 → 0.0.76

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 (146) hide show
  1. package/dist/src/cli.js +210 -41
  2. package/dist/src/commands/brain.js +7 -13
  3. package/dist/src/commands/schedule.js +4 -2
  4. package/dist/src/commands/{secret.js → secrets.js} +13 -13
  5. package/dist/src/components/brain-history.js +8 -8
  6. package/dist/src/components/brain-kill.js +4 -2
  7. package/dist/src/components/brain-list.js +104 -17
  8. package/dist/src/components/brain-rerun.js +21 -30
  9. package/dist/src/components/brain-run.js +10 -6
  10. package/dist/src/components/brain-show.js +89 -2
  11. package/dist/src/components/brain-top.js +3 -17
  12. package/dist/src/components/event-detail.js +66 -0
  13. package/dist/src/components/events-view.js +12 -0
  14. package/dist/src/components/page-delete.js +2 -0
  15. package/dist/src/components/pages-list.js +7 -7
  16. package/dist/src/components/project-add.js +1 -1
  17. package/dist/src/components/project-auth-setup.js +5 -2
  18. package/dist/src/components/project-create.js +8 -2
  19. package/dist/src/components/project-list.js +2 -2
  20. package/dist/src/components/project-remove.js +1 -1
  21. package/dist/src/components/project-show.js +1 -1
  22. package/dist/src/components/resource-clear.js +1 -1
  23. package/dist/src/components/resource-delete.js +5 -2
  24. package/dist/src/components/resource-list.js +2 -2
  25. package/dist/src/components/resource-sync.js +5 -5
  26. package/dist/src/components/resource-upload.js +1 -1
  27. package/dist/src/components/schedule-create.js +43 -5
  28. package/dist/src/components/schedule-delete.js +4 -2
  29. package/dist/src/components/schedule-list.js +14 -14
  30. package/dist/src/components/schedule-runs.js +7 -7
  31. package/dist/src/components/{secret-bulk.js → secrets-bulk.js} +2 -2
  32. package/dist/src/components/{secret-create.js → secrets-create.js} +3 -3
  33. package/dist/src/components/{secret-delete.js → secrets-delete.js} +1 -1
  34. package/dist/src/components/{secret-list.js → secrets-list.js} +4 -4
  35. package/dist/src/components/store-explorer.js +4 -17
  36. package/dist/src/components/top-navigator.js +3 -17
  37. package/dist/src/components/users-keys-list.js +4 -4
  38. package/dist/src/components/users-keys-remove.js +1 -1
  39. package/dist/src/components/users-list.js +2 -2
  40. package/dist/src/components/watch.js +50 -33
  41. package/dist/src/components/whoami.js +1 -1
  42. package/dist/src/hooks/useAlternateScreen.js +18 -0
  43. package/dist/src/hooks/useApi.js +1 -1
  44. package/dist/types/cli.d.ts.map +1 -1
  45. package/dist/types/commands/brain.d.ts +5 -6
  46. package/dist/types/commands/brain.d.ts.map +1 -1
  47. package/dist/types/commands/helpers.d.ts.map +1 -1
  48. package/dist/types/commands/pages.d.ts +1 -1
  49. package/dist/types/commands/pages.d.ts.map +1 -1
  50. package/dist/types/commands/project-config-manager.d.ts.map +1 -1
  51. package/dist/types/commands/schedule.d.ts +4 -2
  52. package/dist/types/commands/schedule.d.ts.map +1 -1
  53. package/dist/types/commands/{secret.d.ts → secrets.d.ts} +2 -2
  54. package/dist/types/commands/secrets.d.ts.map +1 -0
  55. package/dist/types/commands/server.d.ts.map +1 -1
  56. package/dist/types/commands/users.d.ts +2 -2
  57. package/dist/types/commands/users.d.ts.map +1 -1
  58. package/dist/types/components/auth-login.d.ts +1 -1
  59. package/dist/types/components/auth-login.d.ts.map +1 -1
  60. package/dist/types/components/auth-logout.d.ts +1 -1
  61. package/dist/types/components/auth-logout.d.ts.map +1 -1
  62. package/dist/types/components/brain-history.d.ts.map +1 -1
  63. package/dist/types/components/brain-kill.d.ts.map +1 -1
  64. package/dist/types/components/brain-list.d.ts.map +1 -1
  65. package/dist/types/components/brain-rerun.d.ts +3 -5
  66. package/dist/types/components/brain-rerun.d.ts.map +1 -1
  67. package/dist/types/components/brain-resolver.d.ts.map +1 -1
  68. package/dist/types/components/brain-run.d.ts +2 -1
  69. package/dist/types/components/brain-run.d.ts.map +1 -1
  70. package/dist/types/components/brain-show.d.ts +5 -0
  71. package/dist/types/components/brain-show.d.ts.map +1 -1
  72. package/dist/types/components/brain-top-table.d.ts.map +1 -1
  73. package/dist/types/components/brain-top.d.ts.map +1 -1
  74. package/dist/types/components/brain-watch.d.ts +1 -1
  75. package/dist/types/components/brain-watch.d.ts.map +1 -1
  76. package/dist/types/components/error.d.ts.map +1 -1
  77. package/dist/types/components/event-detail.d.ts +1 -1
  78. package/dist/types/components/event-detail.d.ts.map +1 -1
  79. package/dist/types/components/events-view.d.ts.map +1 -1
  80. package/dist/types/components/page-delete.d.ts.map +1 -1
  81. package/dist/types/components/pages-list.d.ts.map +1 -1
  82. package/dist/types/components/project-add.d.ts.map +1 -1
  83. package/dist/types/components/project-auth-setup.d.ts +1 -1
  84. package/dist/types/components/project-auth-setup.d.ts.map +1 -1
  85. package/dist/types/components/project-create.d.ts.map +1 -1
  86. package/dist/types/components/project-list.d.ts.map +1 -1
  87. package/dist/types/components/project-remove.d.ts.map +1 -1
  88. package/dist/types/components/project-select.d.ts.map +1 -1
  89. package/dist/types/components/project-show.d.ts.map +1 -1
  90. package/dist/types/components/resource-clear.d.ts.map +1 -1
  91. package/dist/types/components/resource-delete.d.ts +1 -1
  92. package/dist/types/components/resource-delete.d.ts.map +1 -1
  93. package/dist/types/components/resource-list.d.ts.map +1 -1
  94. package/dist/types/components/resource-sync.d.ts +1 -1
  95. package/dist/types/components/resource-sync.d.ts.map +1 -1
  96. package/dist/types/components/resource-types.d.ts.map +1 -1
  97. package/dist/types/components/resource-upload.d.ts +1 -1
  98. package/dist/types/components/resource-upload.d.ts.map +1 -1
  99. package/dist/types/components/run-show.d.ts.map +1 -1
  100. package/dist/types/components/schedule-create.d.ts +3 -1
  101. package/dist/types/components/schedule-create.d.ts.map +1 -1
  102. package/dist/types/components/schedule-delete.d.ts.map +1 -1
  103. package/dist/types/components/schedule-list.d.ts.map +1 -1
  104. package/dist/types/components/schedule-runs.d.ts +1 -1
  105. package/dist/types/components/schedule-runs.d.ts.map +1 -1
  106. package/dist/types/components/secrets-bulk.d.ts +7 -0
  107. package/dist/types/components/secrets-bulk.d.ts.map +1 -0
  108. package/dist/types/components/secrets-create.d.ts +7 -0
  109. package/dist/types/components/secrets-create.d.ts.map +1 -0
  110. package/dist/types/components/secrets-delete.d.ts +6 -0
  111. package/dist/types/components/secrets-delete.d.ts.map +1 -0
  112. package/dist/types/components/secrets-list.d.ts +2 -0
  113. package/dist/types/components/secrets-list.d.ts.map +1 -0
  114. package/dist/types/components/select-list.d.ts.map +1 -1
  115. package/dist/types/components/state-view.d.ts.map +1 -1
  116. package/dist/types/components/store-explorer.d.ts.map +1 -1
  117. package/dist/types/components/top-navigator.d.ts.map +1 -1
  118. package/dist/types/components/users-create.d.ts.map +1 -1
  119. package/dist/types/components/users-delete.d.ts.map +1 -1
  120. package/dist/types/components/users-keys-add.d.ts +1 -1
  121. package/dist/types/components/users-keys-add.d.ts.map +1 -1
  122. package/dist/types/components/users-keys-list.d.ts.map +1 -1
  123. package/dist/types/components/users-keys-remove.d.ts +1 -1
  124. package/dist/types/components/users-keys-remove.d.ts.map +1 -1
  125. package/dist/types/components/users-list.d.ts.map +1 -1
  126. package/dist/types/components/watch-machine.d.ts.map +1 -1
  127. package/dist/types/components/watch-resolver.d.ts +1 -1
  128. package/dist/types/components/watch-resolver.d.ts.map +1 -1
  129. package/dist/types/components/watch.d.ts +1 -1
  130. package/dist/types/components/watch.d.ts.map +1 -1
  131. package/dist/types/components/whoami.d.ts.map +1 -1
  132. package/dist/types/hooks/useAlternateScreen.d.ts +2 -0
  133. package/dist/types/hooks/useAlternateScreen.d.ts.map +1 -0
  134. package/dist/types/hooks/useApi.d.ts.map +1 -1
  135. package/dist/types/lib/jwt-auth.d.ts.map +1 -1
  136. package/dist/types/lib/ssh-key-utils.d.ts.map +1 -1
  137. package/package.json +4 -4
  138. package/dist/types/commands/secret.d.ts.map +0 -1
  139. package/dist/types/components/secret-bulk.d.ts +0 -7
  140. package/dist/types/components/secret-bulk.d.ts.map +0 -1
  141. package/dist/types/components/secret-create.d.ts +0 -7
  142. package/dist/types/components/secret-create.d.ts.map +0 -1
  143. package/dist/types/components/secret-delete.d.ts +0 -6
  144. package/dist/types/components/secret-delete.d.ts.map +0 -1
  145. package/dist/types/components/secret-list.d.ts +0 -2
  146. package/dist/types/components/secret-list.d.ts.map +0 -1
@@ -3,15 +3,48 @@ function _array_like_to_array(arr, len) {
3
3
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
4
4
  return arr2;
5
5
  }
6
+ function _array_with_holes(arr) {
7
+ if (Array.isArray(arr)) return arr;
8
+ }
6
9
  function _array_without_holes(arr) {
7
10
  if (Array.isArray(arr)) return _array_like_to_array(arr);
8
11
  }
9
12
  function _iterable_to_array(iter) {
10
13
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
11
14
  }
15
+ function _iterable_to_array_limit(arr, i) {
16
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
17
+ if (_i == null) return;
18
+ var _arr = [];
19
+ var _n = true;
20
+ var _d = false;
21
+ var _s, _e;
22
+ try {
23
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
24
+ _arr.push(_s.value);
25
+ if (i && _arr.length === i) break;
26
+ }
27
+ } catch (err) {
28
+ _d = true;
29
+ _e = err;
30
+ } finally{
31
+ try {
32
+ if (!_n && _i["return"] != null) _i["return"]();
33
+ } finally{
34
+ if (_d) throw _e;
35
+ }
36
+ }
37
+ return _arr;
38
+ }
39
+ function _non_iterable_rest() {
40
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
41
+ }
12
42
  function _non_iterable_spread() {
13
43
  throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
14
44
  }
45
+ function _sliced_to_array(arr, i) {
46
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
47
+ }
15
48
  function _to_consumable_array(arr) {
16
49
  return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
17
50
  }
@@ -23,10 +56,12 @@ function _unsupported_iterable_to_array(o, minLen) {
23
56
  if (n === "Map" || n === "Set") return Array.from(n);
24
57
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
25
58
  }
26
- import React from 'react';
27
- import { Text, Box } from 'ink';
59
+ import React, { useState } from 'react';
60
+ import { Text, Box, useInput, useApp } from 'ink';
28
61
  import { ErrorComponent } from './error.js';
29
62
  import { useApiGet } from '../hooks/useApi.js';
63
+ import { BrainInfo } from './brain-show.js';
64
+ import { useAlternateScreen } from '../hooks/useAlternateScreen.js';
30
65
  // Helper to pad text to column width
31
66
  var padRight = function(text, width) {
32
67
  return text + ' '.repeat(Math.max(0, width - text.length));
@@ -71,7 +106,38 @@ var wrapText = function(text, maxWidth) {
71
106
  ];
72
107
  };
73
108
  export var BrainList = function() {
109
+ var exit = useApp().exit;
74
110
  var _useApiGet = useApiGet('/brains'), data = _useApiGet.data, loading = _useApiGet.loading, error = _useApiGet.error;
111
+ var _useState = _sliced_to_array(useState('list'), 2), mode = _useState[0], setMode = _useState[1];
112
+ var _useState1 = _sliced_to_array(useState(0), 2), selectedIndex = _useState1[0], setSelectedIndex = _useState1[1];
113
+ useAlternateScreen();
114
+ // Sort brains alphabetically by title
115
+ var sortedBrains = data ? _to_consumable_array(data.brains).sort(function(a, b) {
116
+ return a.title.localeCompare(b.title);
117
+ }) : [];
118
+ useInput(function(input, key) {
119
+ if (mode === 'list') {
120
+ if ((key.upArrow || input === 'k') && sortedBrains.length > 0) {
121
+ setSelectedIndex(function(prev) {
122
+ return (prev - 1 + sortedBrains.length) % sortedBrains.length;
123
+ });
124
+ } else if ((key.downArrow || input === 'j') && sortedBrains.length > 0) {
125
+ setSelectedIndex(function(prev) {
126
+ return (prev + 1) % sortedBrains.length;
127
+ });
128
+ } else if (key.return && sortedBrains.length > 0) {
129
+ setMode('detail');
130
+ } else if (input === 'q' || key.escape) {
131
+ exit();
132
+ }
133
+ } else if (mode === 'detail') {
134
+ if (key.escape) {
135
+ setMode('list');
136
+ } else if (input === 'q') {
137
+ exit();
138
+ }
139
+ }
140
+ });
75
141
  if (error) {
76
142
  return /*#__PURE__*/ React.createElement(ErrorComponent, {
77
143
  error: error
@@ -89,11 +155,22 @@ export var BrainList = function() {
89
155
  dimColor: true
90
156
  }, 'Tip: Create a brain with "px brain new <name>" or add .ts files to the brains/ directory')));
91
157
  }
92
- // Sort brains alphabetically by title
93
- var sortedBrains = _to_consumable_array(data.brains).sort(function(a, b) {
94
- return a.title.localeCompare(b.title);
95
- });
158
+ // Detail mode - show BrainInfo for the selected brain
159
+ var selectedBrain = sortedBrains[selectedIndex];
160
+ if (mode === 'detail' && selectedBrain) {
161
+ return /*#__PURE__*/ React.createElement(Box, {
162
+ flexDirection: "column"
163
+ }, /*#__PURE__*/ React.createElement(BrainInfo, {
164
+ brainTitle: selectedBrain.title,
165
+ showSteps: true
166
+ }), /*#__PURE__*/ React.createElement(Box, {
167
+ marginTop: 1
168
+ }, /*#__PURE__*/ React.createElement(Text, {
169
+ dimColor: true
170
+ }, "esc back | q quit")));
171
+ }
96
172
  // Define column widths
173
+ var indicatorWidth = 2;
97
174
  var columns = {
98
175
  title: {
99
176
  header: 'Brain',
@@ -104,8 +181,8 @@ export var BrainList = function() {
104
181
  width: 70
105
182
  }
106
183
  };
107
- // Calculate total width for separator
108
- var totalWidth = Object.values(columns).reduce(function(sum, col) {
184
+ // Calculate total width for separator (including indicator column)
185
+ var totalWidth = indicatorWidth + Object.values(columns).reduce(function(sum, col) {
109
186
  return sum + col.width + 2;
110
187
  }, 0) - 2;
111
188
  return /*#__PURE__*/ React.createElement(Box, {
@@ -117,28 +194,38 @@ export var BrainList = function() {
117
194
  }, "Found ", data.count, " brain", data.count === 1 ? '' : 's', ":"), /*#__PURE__*/ React.createElement(Box, {
118
195
  marginTop: 1,
119
196
  flexDirection: "column"
120
- }, /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
197
+ }, /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, null, ' '.repeat(indicatorWidth)), /*#__PURE__*/ React.createElement(Text, {
121
198
  bold: true,
122
199
  color: "cyan"
123
- }, padRight(columns.title.header, columns.title.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
200
+ }, padRight(columns.title.header, columns.title.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
124
201
  bold: true,
125
202
  color: "cyan"
126
203
  }, columns.description.header)), /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
127
204
  dimColor: true
128
- }, '─'.repeat(totalWidth))), sortedBrains.map(function(brain) {
205
+ }, '─'.repeat(totalWidth))), sortedBrains.map(function(brain, index) {
206
+ var isSelected = index === selectedIndex;
129
207
  var descriptionLines = wrapText(brain.description, columns.description.width);
130
208
  return /*#__PURE__*/ React.createElement(Box, {
131
209
  key: brain.filename,
132
210
  flexDirection: "column",
133
- marginBottom: descriptionLines.length > 1 ? 1 : 0
134
- }, /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, null, padRight(brain.title.length > columns.title.width ? brain.title.substring(0, columns.title.width - 3) + '...' : brain.title, columns.title.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
211
+ marginBottom: 1
212
+ }, /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
213
+ color: isSelected ? 'cyan' : undefined
214
+ }, isSelected ? '> ' : ' '), /*#__PURE__*/ React.createElement(Text, {
215
+ bold: isSelected,
216
+ color: isSelected ? 'cyan' : undefined
217
+ }, padRight(brain.title.length > columns.title.width ? brain.title.substring(0, columns.title.width - 3) + '...' : brain.title, columns.title.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
135
218
  dimColor: true
136
- }, descriptionLines[0])), descriptionLines.slice(1).map(function(line, index) {
219
+ }, descriptionLines[0])), descriptionLines.slice(1).map(function(line, lineIndex) {
137
220
  return /*#__PURE__*/ React.createElement(Box, {
138
- key: index
139
- }, /*#__PURE__*/ React.createElement(Text, null, ' '.repeat(columns.title.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
221
+ key: lineIndex
222
+ }, /*#__PURE__*/ React.createElement(Text, null, ' '.repeat(indicatorWidth)), /*#__PURE__*/ React.createElement(Text, null, ' '.repeat(columns.title.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
140
223
  dimColor: true
141
224
  }, line));
142
225
  }));
143
- })));
226
+ })), /*#__PURE__*/ React.createElement(Box, {
227
+ marginTop: 1
228
+ }, /*#__PURE__*/ React.createElement(Text, {
229
+ dimColor: true
230
+ }, "j/k or up/down select | Enter show | esc/q quit")));
144
231
  };
@@ -169,14 +169,15 @@ import { Text, Box } from 'ink';
169
169
  import { apiClient } from '../commands/helpers.js';
170
170
  import { ErrorComponent } from './error.js';
171
171
  export var BrainRerun = function(param) {
172
- var identifier = param.identifier, runId = param.runId, startsAt = param.startsAt, stopsAfter = param.stopsAfter;
172
+ var runId = param.runId, startsAt = param.startsAt;
173
173
  var _useState = _sliced_to_array(useState(true), 2), isLoading = _useState[0], setIsLoading = _useState[1];
174
174
  var _useState1 = _sliced_to_array(useState(null), 2), error = _useState1[0], setError = _useState1[1];
175
- var _useState2 = _sliced_to_array(useState(null), 2), newRunId = _useState2[0], setNewRunId = _useState2[1];
175
+ var _useState2 = _sliced_to_array(useState(false), 2), success = _useState2[0], setSuccess = _useState2[1];
176
+ var _useState3 = _sliced_to_array(useState(null), 2), brainTitle = _useState3[0], setBrainTitle = _useState3[1];
176
177
  useEffect(function() {
177
178
  var rerunBrain = function() {
178
179
  return _async_to_generator(function() {
179
- var body, response, result, errorData, errorText, err;
180
+ var response, data, errorData, errorText, err;
180
181
  return _ts_generator(this, function(_state) {
181
182
  switch(_state.label){
182
183
  case 0:
@@ -186,12 +187,6 @@ export var BrainRerun = function(param) {
186
187
  9,
187
188
  10
188
189
  ]);
189
- body = {
190
- identifier: identifier
191
- };
192
- if (runId) body.runId = runId;
193
- if (startsAt !== undefined) body.startsAt = startsAt;
194
- if (stopsAfter !== undefined) body.stopsAfter = stopsAfter;
195
190
  return [
196
191
  4,
197
192
  apiClient.fetch('/brains/runs/rerun', {
@@ -199,12 +194,15 @@ export var BrainRerun = function(param) {
199
194
  headers: {
200
195
  'Content-Type': 'application/json'
201
196
  },
202
- body: JSON.stringify(body)
197
+ body: JSON.stringify({
198
+ runId: runId,
199
+ startsAt: startsAt
200
+ })
203
201
  })
204
202
  ];
205
203
  case 1:
206
204
  response = _state.sent();
207
- if (!(response.status === 201)) return [
205
+ if (!(response.status === 200)) return [
208
206
  3,
209
207
  3
210
208
  ];
@@ -213,8 +211,9 @@ export var BrainRerun = function(param) {
213
211
  response.json()
214
212
  ];
215
213
  case 2:
216
- result = _state.sent();
217
- setNewRunId(result.brainRunId);
214
+ data = _state.sent();
215
+ setBrainTitle(data.brainTitle);
216
+ setSuccess(true);
218
217
  return [
219
218
  3,
220
219
  7
@@ -230,7 +229,7 @@ export var BrainRerun = function(param) {
230
229
  ];
231
230
  case 4:
232
231
  errorData = _state.sent();
233
- setError(errorData.error || "Brain or run not found");
232
+ setError(errorData.error || "Run not found");
234
233
  return [
235
234
  3,
236
235
  7
@@ -271,36 +270,28 @@ export var BrainRerun = function(param) {
271
270
  };
272
271
  rerunBrain();
273
272
  }, [
274
- identifier,
275
273
  runId,
276
- startsAt,
277
- stopsAfter
274
+ startsAt
278
275
  ]);
279
- var errorDetails = runId ? 'Make sure the brain "'.concat(identifier, '" and run ID "').concat(runId, '" exist.\nYou can list brain history with: positronic brain history ').concat(identifier) : 'Make sure the brain "'.concat(identifier, '" exists.\nYou can list available brains with: positronic brain list');
280
- var runDetails = runId ? " from run ".concat(runId) : '';
281
- var rangeDetails = startsAt || stopsAfter ? " (".concat(startsAt ? "starting at step ".concat(startsAt) : '').concat(startsAt && stopsAfter ? ', ' : '').concat(stopsAfter ? "stopping after step ".concat(stopsAfter) : '', ")") : '';
282
- // Maintain consistent Box wrapper to help Ink properly calculate
283
- // terminal clearing between renders (prevents appending instead of overwriting)
276
+ var errorDetails = 'Make sure run ID "'.concat(runId, '" exists.\nYou can list brain history with: positronic brain history <brain>');
284
277
  return /*#__PURE__*/ React.createElement(Box, {
285
278
  flexDirection: "column"
286
- }, isLoading ? /*#__PURE__*/ React.createElement(Text, null, "\uD83D\uDD04 Starting brain rerun...") : error ? /*#__PURE__*/ React.createElement(ErrorComponent, {
279
+ }, isLoading ? /*#__PURE__*/ React.createElement(Text, null, "Rerunning brain from step ", startsAt, "...") : error ? /*#__PURE__*/ React.createElement(ErrorComponent, {
287
280
  error: {
288
281
  title: 'Brain Rerun Failed',
289
282
  message: error,
290
283
  details: errorDetails
291
284
  }
292
- }) : newRunId ? /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(Text, {
285
+ }) : success ? /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(Text, {
293
286
  bold: true,
294
287
  color: "green"
295
- }, "Brain rerun started successfully!"), /*#__PURE__*/ React.createElement(Text, null, "New run ID: ", /*#__PURE__*/ React.createElement(Text, {
296
- bold: true
297
- }, newRunId)), /*#__PURE__*/ React.createElement(Text, {
288
+ }, "Brain rerun started successfully!"), /*#__PURE__*/ React.createElement(Text, {
298
289
  dimColor: true
299
- }, 'Rerunning brain "', identifier, '"', runDetails, rangeDetails), /*#__PURE__*/ React.createElement(Box, {
290
+ }, 'Rerunning "', brainTitle, '" from step ', startsAt), /*#__PURE__*/ React.createElement(Box, {
300
291
  marginTop: 1
301
292
  }, /*#__PURE__*/ React.createElement(Text, {
302
293
  dimColor: true
303
- }, "Watch the run with: positronic watch ", newRunId))) : /*#__PURE__*/ React.createElement(Text, {
294
+ }, "Watch the run with: positronic watch ", runId))) : /*#__PURE__*/ React.createElement(Text, {
304
295
  color: "red"
305
- }, "Unexpected error occurred"));
296
+ }, "Unexpected error occurred"));
306
297
  };
@@ -321,10 +321,12 @@ var startRun = function(ctx) {
321
321
  headers: {
322
322
  'Content-Type': 'application/json'
323
323
  },
324
- body: JSON.stringify({
324
+ body: JSON.stringify(_object_spread({
325
325
  identifier: ctx.selectedBrainTitle,
326
326
  options: ctx.options
327
- })
327
+ }, ctx.initialState && {
328
+ initialState: ctx.initialState
329
+ }))
328
330
  })
329
331
  ];
330
332
  case 1:
@@ -420,7 +422,7 @@ var brainsMultipleGuard = guard(function(ctx) {
420
422
  return ((_ctx_brainSearchResult_count = (_ctx_brainSearchResult = ctx.brainSearchResult) === null || _ctx_brainSearchResult === void 0 ? void 0 : _ctx_brainSearchResult.count) !== null && _ctx_brainSearchResult_count !== void 0 ? _ctx_brainSearchResult_count : 0) > 1;
421
423
  });
422
424
  // State machine definition
423
- var createBrainRunMachine = function(identifier, watch, options) {
425
+ var createBrainRunMachine = function(identifier, watch, options, initialState) {
424
426
  return createMachine('searching', {
425
427
  // Invoke state: search for brain by name
426
428
  searching: invoke(searchBrains, transition('done', 'routeSearch', storeBrainSearchResult), transition('error', 'error', setErrorFromEvent)),
@@ -438,6 +440,7 @@ var createBrainRunMachine = function(identifier, watch, options) {
438
440
  identifier: identifier,
439
441
  watch: watch,
440
442
  options: options,
443
+ initialState: initialState,
441
444
  brainSearchResult: null,
442
445
  brains: [],
443
446
  selectedBrainTitle: null,
@@ -456,13 +459,14 @@ var createBrainRunMachine = function(identifier, watch, options) {
456
459
  * 3. Start the brain run
457
460
  * 4. Show run ID or Watch component based on watch flag
458
461
  */ export var BrainRun = function(param) {
459
- var identifier = param.identifier, _param_watch = param.watch, watch = _param_watch === void 0 ? false : _param_watch, options = param.options;
462
+ var identifier = param.identifier, _param_watch = param.watch, watch = _param_watch === void 0 ? false : _param_watch, options = param.options, initialState = param.initialState;
460
463
  var machine = useMemo(function() {
461
- return createBrainRunMachine(identifier, watch, options);
464
+ return createBrainRunMachine(identifier, watch, options, initialState);
462
465
  }, [
463
466
  identifier,
464
467
  watch,
465
- options
468
+ options,
469
+ initialState
466
470
  ]);
467
471
  var _useMachine = _sliced_to_array(useMachine(machine), 2), current = _useMachine[0], send = _useMachine[1];
468
472
  var exit = useApp().exit;
@@ -1,3 +1,49 @@
1
+ function _array_like_to_array(arr, len) {
2
+ if (len == null || len > arr.length) len = arr.length;
3
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
4
+ return arr2;
5
+ }
6
+ function _array_with_holes(arr) {
7
+ if (Array.isArray(arr)) return arr;
8
+ }
9
+ function _iterable_to_array_limit(arr, i) {
10
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
11
+ if (_i == null) return;
12
+ var _arr = [];
13
+ var _n = true;
14
+ var _d = false;
15
+ var _s, _e;
16
+ try {
17
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
18
+ _arr.push(_s.value);
19
+ if (i && _arr.length === i) break;
20
+ }
21
+ } catch (err) {
22
+ _d = true;
23
+ _e = err;
24
+ } finally{
25
+ try {
26
+ if (!_n && _i["return"] != null) _i["return"]();
27
+ } finally{
28
+ if (_d) throw _e;
29
+ }
30
+ }
31
+ return _arr;
32
+ }
33
+ function _non_iterable_rest() {
34
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
35
+ }
36
+ function _sliced_to_array(arr, i) {
37
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
38
+ }
39
+ function _unsupported_iterable_to_array(o, minLen) {
40
+ if (!o) return;
41
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
42
+ var n = Object.prototype.toString.call(o).slice(8, -1);
43
+ if (n === "Object" && o.constructor) n = o.constructor.name;
44
+ if (n === "Map" || n === "Set") return Array.from(n);
45
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
46
+ }
1
47
  import React from 'react';
2
48
  import { Text, Box } from 'ink';
3
49
  import { useApiGet } from '../hooks/useApi.js';
@@ -42,7 +88,45 @@ var StepTree = function(param) {
42
88
  }))));
43
89
  }));
44
90
  };
45
- var BrainInfo = function(param) {
91
+ // Component for rendering options
92
+ var OptionsSection = function(param) {
93
+ var options = param.options, brainTitle = param.brainTitle;
94
+ var properties = options.properties, required = options.required;
95
+ if (!properties || Object.keys(properties).length === 0) {
96
+ return null;
97
+ }
98
+ var entries = Object.entries(properties);
99
+ var requiredSet = new Set(required || []);
100
+ var flags = entries.map(function(param) {
101
+ var _param = _sliced_to_array(param, 2), name = _param[0], prop = _param[1];
102
+ return "-o ".concat(name, "=<").concat(prop.type || 'any', ">");
103
+ }).join(' ');
104
+ return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(Box, {
105
+ flexDirection: "column"
106
+ }, /*#__PURE__*/ React.createElement(Text, {
107
+ bold: true
108
+ }, "Options:"), /*#__PURE__*/ React.createElement(Box, {
109
+ marginLeft: 2,
110
+ flexDirection: "column"
111
+ }, entries.map(function(param) {
112
+ var _param = _sliced_to_array(param, 2), name = _param[0], prop = _param[1];
113
+ var isRequired = requiredSet.has(name);
114
+ return /*#__PURE__*/ React.createElement(Box, {
115
+ key: name
116
+ }, /*#__PURE__*/ React.createElement(Text, null, name, /*#__PURE__*/ React.createElement(Text, {
117
+ dimColor: true
118
+ }, ' ', prop.type || 'any', isRequired ? ', required' : '')));
119
+ }))), /*#__PURE__*/ React.createElement(Box, {
120
+ flexDirection: "column"
121
+ }, /*#__PURE__*/ React.createElement(Text, {
122
+ bold: true
123
+ }, "Example:"), /*#__PURE__*/ React.createElement(Box, {
124
+ marginLeft: 2
125
+ }, /*#__PURE__*/ React.createElement(Text, {
126
+ dimColor: true
127
+ }, "px run ", brainTitle, " ", flags))));
128
+ };
129
+ export var BrainInfo = function(param) {
46
130
  var brainTitle = param.brainTitle, showSteps = param.showSteps;
47
131
  var _useApiGet = useApiGet("/brains/".concat(encodeURIComponent(brainTitle))), brain = _useApiGet.data, brainLoading = _useApiGet.loading, brainError = _useApiGet.error;
48
132
  var _useApiGet1 = useApiGet('/brains/schedules'), schedulesData = _useApiGet1.data, schedulesLoading = _useApiGet1.loading;
@@ -74,7 +158,10 @@ var BrainInfo = function(param) {
74
158
  bold: true
75
159
  }, brain.title)), brain.description && /*#__PURE__*/ React.createElement(Field, {
76
160
  label: "Description"
77
- }, /*#__PURE__*/ React.createElement(Text, null, brain.description))), showSteps && brain.steps.length > 0 && /*#__PURE__*/ React.createElement(Box, {
161
+ }, /*#__PURE__*/ React.createElement(Text, null, brain.description))), brain.options && /*#__PURE__*/ React.createElement(OptionsSection, {
162
+ options: brain.options,
163
+ brainTitle: brain.title
164
+ }), showSteps && brain.steps.length > 0 && /*#__PURE__*/ React.createElement(Box, {
78
165
  flexDirection: "column"
79
166
  }, /*#__PURE__*/ React.createElement(Text, {
80
167
  bold: true
@@ -45,35 +45,21 @@ function _unsupported_iterable_to_array(o, minLen) {
45
45
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
46
46
  }
47
47
  import React, { useState, useEffect, useRef } from 'react';
48
- import { Text, Box, useStdout } from 'ink';
48
+ import { Text, Box } from 'ink';
49
49
  import { EventSource } from 'eventsource';
50
50
  import { getApiBaseUrl, isApiLocalDevMode } from '../commands/helpers.js';
51
51
  import { ErrorComponent } from './error.js';
52
52
  import { BrainTopTable } from './brain-top-table.js';
53
+ import { useAlternateScreen } from '../hooks/useAlternateScreen.js';
53
54
  export var BrainTop = function(param) {
54
55
  var brainFilter = param.brainFilter;
55
- var write = useStdout().write;
56
56
  var _useState = _sliced_to_array(useState([]), 2), runningBrains = _useState[0], setRunningBrains = _useState[1];
57
57
  var _useState1 = _sliced_to_array(useState(null), 2), error = _useState1[0], setError = _useState1[1];
58
58
  var _useState2 = _sliced_to_array(useState(false), 2), isConnected = _useState2[0], setIsConnected = _useState2[1];
59
59
  var _useState3 = _sliced_to_array(useState(0), 2), setTick = _useState3[1];
60
60
  var eventSourceRef = useRef(null);
61
61
  var hasReceivedDataRef = useRef(false);
62
- // Enter alternate screen buffer on mount, exit on unmount
63
- // Skip in test environment to avoid interfering with test output capture
64
- useEffect(function() {
65
- if (process.env.NODE_ENV === 'test') {
66
- return;
67
- }
68
- // Enter alternate screen buffer and clear
69
- write('\x1B[?1049h\x1B[2J\x1B[H');
70
- return function() {
71
- // Exit alternate screen buffer
72
- write('\x1B[?1049l');
73
- };
74
- }, [
75
- write
76
- ]);
62
+ useAlternateScreen();
77
63
  // Update tick every second to refresh duration display
78
64
  useEffect(function() {
79
65
  var interval = setInterval(function() {
@@ -144,6 +144,31 @@ function getEventSymbol(event) {
144
144
  symbol: '[W]',
145
145
  color: 'cyan'
146
146
  };
147
+ case BRAIN_EVENTS.AGENT_RAW_RESPONSE_MESSAGE:
148
+ return {
149
+ symbol: '[~]',
150
+ color: 'gray'
151
+ };
152
+ case BRAIN_EVENTS.PAUSED:
153
+ return {
154
+ symbol: '[||]',
155
+ color: 'cyan'
156
+ };
157
+ case BRAIN_EVENTS.RESUMED:
158
+ return {
159
+ symbol: '[>]',
160
+ color: 'green'
161
+ };
162
+ case BRAIN_EVENTS.ITERATE_ITEM_COMPLETE:
163
+ return {
164
+ symbol: '[i]',
165
+ color: 'green'
166
+ };
167
+ case BRAIN_EVENTS.AGENT_USER_MESSAGE:
168
+ return {
169
+ symbol: '[U]',
170
+ color: 'cyan'
171
+ };
147
172
  default:
148
173
  return {
149
174
  symbol: '[?]',
@@ -303,6 +328,47 @@ function getEventDetailContent(event) {
303
328
  '',
304
329
  'Agent waiting for webhook response...'
305
330
  ].join('\n');
331
+ case BRAIN_EVENTS.AGENT_RAW_RESPONSE_MESSAGE:
332
+ return [
333
+ "Step: ".concat(event.stepTitle),
334
+ "Iteration: ".concat(event.iteration),
335
+ '',
336
+ 'Raw Response Message:',
337
+ JSON.stringify(event.message, null, 2)
338
+ ].join('\n');
339
+ case BRAIN_EVENTS.PAUSED:
340
+ return [
341
+ "Brain: ".concat(event.brainTitle),
342
+ '',
343
+ 'Brain paused.'
344
+ ].join('\n');
345
+ case BRAIN_EVENTS.RESUMED:
346
+ return [
347
+ "Brain: ".concat(event.brainTitle),
348
+ '',
349
+ 'Brain resumed.'
350
+ ].join('\n');
351
+ case BRAIN_EVENTS.ITERATE_ITEM_COMPLETE:
352
+ return [
353
+ "Step: ".concat(event.stepTitle),
354
+ "Progress: ".concat(event.processedCount, "/").concat(event.totalItems),
355
+ "Item Index: ".concat(event.itemIndex),
356
+ "Schema: ".concat(event.schemaName),
357
+ '',
358
+ 'Item:',
359
+ JSON.stringify(event.item, null, 2),
360
+ '',
361
+ 'Result:',
362
+ JSON.stringify(event.result, null, 2)
363
+ ].join('\n');
364
+ case BRAIN_EVENTS.AGENT_USER_MESSAGE:
365
+ return [
366
+ "Step: ".concat(event.stepTitle),
367
+ "Step ID: ".concat(event.stepId),
368
+ '',
369
+ 'Message:',
370
+ event.content
371
+ ].join('\n');
306
372
  default:
307
373
  // Show all fields for any event type
308
374
  return JSON.stringify(event, null, 2);
@@ -203,6 +203,18 @@ function formatEvent(event) {
203
203
  text: 'Brain resumed: "'.concat(event.brainTitle, '"'),
204
204
  color: 'green'
205
205
  };
206
+ case BRAIN_EVENTS.ITERATE_ITEM_COMPLETE:
207
+ return {
208
+ symbol: '[i]',
209
+ text: "Item ".concat(event.processedCount, "/").concat(event.totalItems, ' complete: "').concat(event.stepTitle, '"'),
210
+ color: 'green'
211
+ };
212
+ case BRAIN_EVENTS.AGENT_USER_MESSAGE:
213
+ return {
214
+ symbol: '[U]',
215
+ text: 'User message: "'.concat(truncate(event.content, 50), '"'),
216
+ color: 'cyan'
217
+ };
206
218
  default:
207
219
  return {
208
220
  symbol: '[?]',
@@ -69,8 +69,10 @@ export var PageDelete = function(param) {
69
69
  exit();
70
70
  }
71
71
  } else if (char === '\u0003') {
72
+ // Ctrl+C
72
73
  exit();
73
74
  } else if (char === '\u007F' || char === '\b') {
75
+ // Backspace
74
76
  setInput(function(prev) {
75
77
  return prev.slice(0, -1);
76
78
  });
@@ -109,16 +109,16 @@ export var PagesList = function() {
109
109
  }, /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
110
110
  bold: true,
111
111
  color: "cyan"
112
- }, padRight(columns.slug.header, columns.slug.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
112
+ }, padRight(columns.slug.header, columns.slug.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
113
113
  bold: true,
114
114
  color: "cyan"
115
- }, padRight(columns.persist.header, columns.persist.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
115
+ }, padRight(columns.persist.header, columns.persist.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
116
116
  bold: true,
117
117
  color: "cyan"
118
- }, padRight(columns.size.header, columns.size.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
118
+ }, padRight(columns.size.header, columns.size.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
119
119
  bold: true,
120
120
  color: "cyan"
121
- }, padRight(columns.brainRunId.header, columns.brainRunId.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
121
+ }, padRight(columns.brainRunId.header, columns.brainRunId.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
122
122
  bold: true,
123
123
  color: "cyan"
124
124
  }, padRight(columns.created.header, columns.created.width))), /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
@@ -126,11 +126,11 @@ export var PagesList = function() {
126
126
  }, '─'.repeat(totalWidth))), sortedPages.map(function(page) {
127
127
  return /*#__PURE__*/ React.createElement(Box, {
128
128
  key: page.slug
129
- }, /*#__PURE__*/ React.createElement(Text, null, padRight(truncate(page.slug, columns.slug.width), columns.slug.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
129
+ }, /*#__PURE__*/ React.createElement(Text, null, padRight(truncate(page.slug, columns.slug.width), columns.slug.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
130
130
  color: page.persist ? 'green' : 'yellow'
131
- }, padRight(page.persist ? 'Yes' : 'No', columns.persist.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, null, padRight(formatSize(page.size), columns.size.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
131
+ }, padRight(page.persist ? 'Yes' : 'No', columns.persist.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, null, padRight(formatSize(page.size), columns.size.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
132
132
  dimColor: true
133
- }, padRight(truncate(page.brainRunId, columns.brainRunId.width), columns.brainRunId.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
133
+ }, padRight(truncate(page.brainRunId, columns.brainRunId.width), columns.brainRunId.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
134
134
  dimColor: true
135
135
  }, padRight(formatDate(page.createdAt), columns.created.width)));
136
136
  })), /*#__PURE__*/ React.createElement(Box, {