@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
@@ -75,7 +75,7 @@ export var ProjectAdd = function(param) {
75
75
  bold: true
76
76
  }, "URL:"), " ", url), isCurrentProject && /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
77
77
  bold: true
78
- }, "Status:"), " ", /*#__PURE__*/ React.createElement(Text, {
78
+ }, "Status:"), ' ', /*#__PURE__*/ React.createElement(Text, {
79
79
  color: "cyan"
80
80
  }, "Current project"))), /*#__PURE__*/ React.createElement(Box, {
81
81
  marginTop: 1
@@ -57,7 +57,7 @@ import { ProjectConfigManager } from '../commands/project-config-manager.js';
57
57
  import { discoverSSHKeys, generateSSHKey, convertSSHPubKeyToJWK } from '../lib/ssh-key-utils.js';
58
58
  import { resetJwtAuthProvider } from '../lib/jwt-auth.js';
59
59
  import { SelectList } from './select-list.js';
60
- import { appendFileSync, existsSync, writeFileSync } from 'fs';
60
+ import { appendFileSync, existsSync, readFileSync, writeFileSync } from 'fs';
61
61
  import { join } from 'path';
62
62
  export var ProjectAuthSetup = function(param) {
63
63
  var projectDir = param.projectDir, onComplete = param.onComplete;
@@ -125,7 +125,10 @@ export var ProjectAuthSetup = function(param) {
125
125
  var envPath = join(projectDir, '.env');
126
126
  var envLine = "ROOT_PUBLIC_KEY='".concat(jwkString, "'\n");
127
127
  if (existsSync(envPath)) {
128
- appendFileSync(envPath, envLine);
128
+ // Ensure we start on a new line if the file doesn't end with one
129
+ var existing = readFileSync(envPath, 'utf-8');
130
+ var prefix = existing.length > 0 && !existing.endsWith('\n') ? '\n' : '';
131
+ appendFileSync(envPath, prefix + envLine);
129
132
  } else {
130
133
  writeFileSync(envPath, envLine);
131
134
  }
@@ -302,7 +302,13 @@ export var ProjectCreate = function(param) {
302
302
  bold: true
303
303
  }, "2."), " Install dependencies if you didn't choose to during setup (e.g., npm install)"), /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
304
304
  bold: true
305
- }, "3."), " Run the development server: px s or positronic server"), /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
305
+ }, "3."), " Add your AI provider API key to .env (e.g., GOOGLE_GENERATIVE_AI_API_KEY)"), /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
306
306
  bold: true
307
- }, "4."), " Open a new terminal in '", projectName, "' and run a brain: px run example --watch"))));
307
+ }, "4."), " Run the development server: px s or positronic server"), /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
308
+ bold: true
309
+ }, "5."), " Open a new terminal in '", projectName, "' and run a brain: px run example --watch")), /*#__PURE__*/ React.createElement(Box, {
310
+ marginTop: 1
311
+ }, /*#__PURE__*/ React.createElement(Text, {
312
+ dimColor: true
313
+ }, "See runner.ts to switch to a different AI provider (e.g., Anthropic, OpenAI)"))));
308
314
  };
@@ -57,7 +57,7 @@ export var ProjectList = function(param) {
57
57
  }, /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
58
58
  bold: true,
59
59
  color: "cyan"
60
- }, padRight('Name', nameColWidth)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
60
+ }, padRight('Name', nameColWidth)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
61
61
  bold: true,
62
62
  color: "cyan"
63
63
  }, "URL")), /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
@@ -68,7 +68,7 @@ export var ProjectList = function(param) {
68
68
  key: project.name
69
69
  }, /*#__PURE__*/ React.createElement(Text, {
70
70
  color: isCurrent ? 'green' : undefined
71
- }, padRight(truncate(project.name, nameColWidth - 2), nameColWidth)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
71
+ }, padRight(truncate(project.name, nameColWidth - 2), nameColWidth)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
72
72
  dimColor: !isCurrent
73
73
  }, project.url), isCurrent && /*#__PURE__*/ React.createElement(Text, {
74
74
  color: "green"
@@ -71,7 +71,7 @@ export var ProjectRemove = function(param) {
71
71
  paddingLeft: 2
72
72
  }, /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
73
73
  bold: true
74
- }, "Current project:"), " ", /*#__PURE__*/ React.createElement(Text, {
74
+ }, "Current project:"), ' ', /*#__PURE__*/ React.createElement(Text, {
75
75
  color: "cyan"
76
76
  }, currentProject))), /*#__PURE__*/ React.createElement(Box, {
77
77
  marginTop: 1
@@ -33,7 +33,7 @@ export var ProjectShow = function(param) {
33
33
  bold: true
34
34
  }, "URL:"), " ", currentProject.url), /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
35
35
  bold: true
36
- }, "Added:"), " ", new Date(currentProject.addedAt).toLocaleString())), projects.length > 1 && /*#__PURE__*/ React.createElement(Box, {
36
+ }, "Added:"), ' ', new Date(currentProject.addedAt).toLocaleString())), projects.length > 1 && /*#__PURE__*/ React.createElement(Box, {
37
37
  marginTop: 1
38
38
  }, /*#__PURE__*/ React.createElement(Text, {
39
39
  dimColor: true
@@ -141,7 +141,7 @@ export var ResourceClear = function() {
141
141
  }, selectedOption === 'delete' ? '▶ ' : ' ', "Delete all resources"))));
142
142
  }
143
143
  if (deleteLoading) {
144
- return /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, null, "\uD83D\uDDD1️ Deleting all resources..."));
144
+ return /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, null, "\uD83D\uDDD1️ Deleting all resources..."));
145
145
  }
146
146
  if (deleted) {
147
147
  return /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
@@ -87,8 +87,10 @@ export var ResourceDelete = function(param) {
87
87
  exit();
88
88
  }
89
89
  } else if (char === '\u0003') {
90
+ // Ctrl+C
90
91
  exit();
91
92
  } else if (char === '\u007F' || char === '\b') {
93
+ // Backspace
92
94
  setInput(function(prev) {
93
95
  return prev.slice(0, -1);
94
96
  });
@@ -122,6 +124,7 @@ export var ResourceDelete = function(param) {
122
124
  // Generate types after successful deletion if in local dev mode
123
125
  if (projectRootPath) {
124
126
  generateTypes(projectRootPath).catch(function(typeError) {
127
+ // Don't fail the delete if type generation fails
125
128
  console.error('Failed to generate types:', typeError);
126
129
  });
127
130
  }
@@ -169,14 +172,14 @@ export var ResourceDelete = function(param) {
169
172
  }, /*#__PURE__*/ React.createElement(Text, {
170
173
  bold: true,
171
174
  color: "yellow"
172
- }, "⚠️ Warning: This will permanently delete the following resource:"), /*#__PURE__*/ React.createElement(Box, {
175
+ }, "⚠️ Warning: This will permanently delete the following resource:"), /*#__PURE__*/ React.createElement(Box, {
173
176
  marginTop: 1,
174
177
  marginBottom: 1,
175
178
  paddingLeft: 2
176
179
  }, /*#__PURE__*/ React.createElement(Text, null, resourcePath)), /*#__PURE__*/ React.createElement(Text, null, 'Type "yes" to confirm deletion: ', input));
177
180
  }
178
181
  if (loading) {
179
- return /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, null, "\uD83D\uDDD1️ Deleting ", resourcePath, "..."));
182
+ return /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, null, "\uD83D\uDDD1️ Deleting ", resourcePath, "..."));
180
183
  }
181
184
  if (deleted) {
182
185
  return /*#__PURE__*/ React.createElement(Box, {
@@ -100,7 +100,7 @@ export var ResourceList = function() {
100
100
  marginTop: 1
101
101
  }, /*#__PURE__*/ React.createElement(Text, {
102
102
  color: "yellow"
103
- }, "⚠️ Results truncated. More resources exist than shown.")), resources.some(function(r) {
103
+ }, "⚠️ Results truncated. More resources exist than shown.")), resources.some(function(r) {
104
104
  return !r.local;
105
105
  }) && /*#__PURE__*/ React.createElement(Box, {
106
106
  marginTop: 1,
@@ -153,7 +153,7 @@ var TreeView = function(param) {
153
153
  color: isRemote ? 'blueBright' : undefined
154
154
  }, node.name, node.resource && /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(Text, {
155
155
  color: isRemote ? 'blueBright' : 'gray'
156
- }, " (", formatSize(node.resource.size), ")"), isRemote && /*#__PURE__*/ React.createElement(Text, {
156
+ }, ' ', "(", formatSize(node.resource.size), ")"), isRemote && /*#__PURE__*/ React.createElement(Text, {
157
157
  color: "blueBright"
158
158
  }, " ↗")))), children.map(function(param, index) {
159
159
  var _param = _sliced_to_array(param, 2), name = _param[0], child = _param[1];
@@ -341,7 +341,7 @@ export var ResourceSync = function(param) {
341
341
  flexDirection: "column"
342
342
  }, error ? /*#__PURE__*/ React.createElement(ErrorComponent, {
343
343
  error: error
344
- }) : currentAction === 'connecting' ? /*#__PURE__*/ React.createElement(Text, null, "\uD83D\uDD0C Connecting to server...") : /*#__PURE__*/ React.createElement(React.Fragment, null, currentAction !== 'done' && currentFile && /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, null, currentAction === 'uploading' ? '⬆️ Uploading' : currentAction === 'deleting' ? '🗑️ Deleting' : '🔍 Checking', " ", currentFile, "...")), totalCount > 0 && currentAction !== 'done' && /*#__PURE__*/ React.createElement(Box, {
344
+ }) : currentAction === 'connecting' ? /*#__PURE__*/ React.createElement(Text, null, "\uD83D\uDD0C Connecting to server...") : /*#__PURE__*/ React.createElement(React.Fragment, null, currentAction !== 'done' && currentFile && /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, null, currentAction === 'uploading' ? '⬆️ Uploading' : currentAction === 'deleting' ? '🗑️ Deleting' : '🔍 Checking', ' ', currentFile, "...")), totalCount > 0 && currentAction !== 'done' && /*#__PURE__*/ React.createElement(Box, {
345
345
  marginTop: 1
346
346
  }, /*#__PURE__*/ React.createElement(Text, {
347
347
  dimColor: true
@@ -372,11 +372,11 @@ export var ResourceSync = function(param) {
372
372
  flexDirection: "column"
373
373
  }, /*#__PURE__*/ React.createElement(Text, {
374
374
  color: "green"
375
- }, " • Uploaded: ", uploadCount), /*#__PURE__*/ React.createElement(Text, {
375
+ }, " • Uploaded: ", uploadCount), /*#__PURE__*/ React.createElement(Text, {
376
376
  color: "blue"
377
- }, " • Skipped (up to date): ", skipCount), deleteCount > 0 && /*#__PURE__*/ React.createElement(Text, {
377
+ }, " • Skipped (up to date): ", skipCount), deleteCount > 0 && /*#__PURE__*/ React.createElement(Text, {
378
378
  color: "yellow"
379
- }, " • Deleted: ", deleteCount), errorCount > 0 && /*#__PURE__*/ React.createElement(Text, {
379
+ }, " • Deleted: ", deleteCount), errorCount > 0 && /*#__PURE__*/ React.createElement(Text, {
380
380
  color: "red"
381
- }, " • Errors: ", errorCount)))));
381
+ }, " • Errors: ", errorCount)))));
382
382
  };
@@ -335,7 +335,7 @@ export var ResourceUpload = function(param) {
335
335
  if (uploading && progress) {
336
336
  return /*#__PURE__*/ React.createElement(Box, {
337
337
  flexDirection: "column"
338
- }, /*#__PURE__*/ React.createElement(Text, null, "⬆️ Uploading ", path.basename(filePath), "..."), /*#__PURE__*/ React.createElement(Box, {
338
+ }, /*#__PURE__*/ React.createElement(Text, null, "⬆️ Uploading ", path.basename(filePath), "..."), /*#__PURE__*/ React.createElement(Box, {
339
339
  marginTop: 1
340
340
  }, /*#__PURE__*/ React.createElement(Text, {
341
341
  dimColor: true
@@ -35,6 +35,19 @@ function _async_to_generator(fn) {
35
35
  });
36
36
  };
37
37
  }
38
+ function _define_property(obj, key, value) {
39
+ if (key in obj) {
40
+ Object.defineProperty(obj, key, {
41
+ value: value,
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true
45
+ });
46
+ } else {
47
+ obj[key] = value;
48
+ }
49
+ return obj;
50
+ }
38
51
  function _iterable_to_array_limit(arr, i) {
39
52
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
40
53
  if (_i == null) return;
@@ -62,6 +75,21 @@ function _iterable_to_array_limit(arr, i) {
62
75
  function _non_iterable_rest() {
63
76
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
64
77
  }
78
+ function _object_spread(target) {
79
+ for(var i = 1; i < arguments.length; i++){
80
+ var source = arguments[i] != null ? arguments[i] : {};
81
+ var ownKeys = Object.keys(source);
82
+ if (typeof Object.getOwnPropertySymbols === "function") {
83
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
84
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
85
+ }));
86
+ }
87
+ ownKeys.forEach(function(key) {
88
+ _define_property(target, key, source[key]);
89
+ });
90
+ }
91
+ return target;
92
+ }
65
93
  function _sliced_to_array(arr, i) {
66
94
  return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
67
95
  }
@@ -169,7 +197,7 @@ import { Box, Text } from 'ink';
169
197
  import { ErrorComponent } from './error.js';
170
198
  import { useApiPost } from '../hooks/useApi.js';
171
199
  export var ScheduleCreate = function(param) {
172
- var identifier = param.identifier, cronExpression = param.cronExpression;
200
+ var identifier = param.identifier, cronExpression = param.cronExpression, options = param.options, initialState = param.initialState;
173
201
  var _useState = _sliced_to_array(useState(false), 2), created = _useState[0], setCreated = _useState[1];
174
202
  var _useState1 = _sliced_to_array(useState(null), 2), schedule = _useState1[0], setSchedule = _useState1[1];
175
203
  var _useApiPost = useApiPost('/brains/schedules', {
@@ -192,10 +220,13 @@ export var ScheduleCreate = function(param) {
192
220
  ]);
193
221
  return [
194
222
  4,
195
- execute({
223
+ execute(_object_spread({
196
224
  identifier: identifier,
197
- cronExpression: cronExpression
198
- })
225
+ cronExpression: cronExpression,
226
+ options: options
227
+ }, initialState && {
228
+ initialState: initialState
229
+ }))
199
230
  ];
200
231
  case 1:
201
232
  result = _state.sent();
@@ -248,7 +279,14 @@ export var ScheduleCreate = function(param) {
248
279
  bold: true
249
280
  }, "Timezone:"), " ", schedule.timezone), /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
250
281
  bold: true
251
- }, "Status:"), " ", schedule.enabled ? 'Enabled' : 'Disabled'), schedule.nextRunAt && /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
282
+ }, "Status:"), ' ', schedule.enabled ? 'Enabled' : 'Disabled'), options && Object.keys(options).length > 0 && /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
283
+ bold: true
284
+ }, "Options:"), ' ', Object.entries(options).map(function(param) {
285
+ var _param = _sliced_to_array(param, 2), k = _param[0], v = _param[1];
286
+ return "".concat(k, "=").concat(v);
287
+ }).join(', ')), initialState && Object.keys(initialState).length > 0 && /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
288
+ bold: true
289
+ }, "Initial State:"), " ", JSON.stringify(initialState)), schedule.nextRunAt && /*#__PURE__*/ React.createElement(Text, null, /*#__PURE__*/ React.createElement(Text, {
252
290
  bold: true
253
291
  }, "Next Run:"), ' ', new Date(schedule.nextRunAt).toLocaleString('en-US', {
254
292
  timeZone: schedule.timezone,
@@ -69,8 +69,10 @@ export var ScheduleDelete = 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
  });
@@ -128,7 +130,7 @@ export var ScheduleDelete = function(param) {
128
130
  });
129
131
  }
130
132
  if (loading) {
131
- return /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, null, "\uD83D\uDDD1️ Deleting schedule..."));
133
+ return /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, null, "\uD83D\uDDD1️ Deleting schedule..."));
132
134
  }
133
135
  if (deleted) {
134
136
  return /*#__PURE__*/ React.createElement(Box, {
@@ -148,7 +150,7 @@ export var ScheduleDelete = function(param) {
148
150
  }, /*#__PURE__*/ React.createElement(Text, {
149
151
  bold: true,
150
152
  color: "yellow"
151
- }, "⚠️ Warning: This will permanently delete the schedule"), /*#__PURE__*/ React.createElement(Box, {
153
+ }, "⚠️ Warning: This will permanently delete the schedule"), /*#__PURE__*/ React.createElement(Box, {
152
154
  marginTop: 1,
153
155
  marginBottom: 1,
154
156
  paddingLeft: 2,
@@ -91,7 +91,7 @@ export var ScheduleList = function(param) {
91
91
  marginTop: 1
92
92
  }, /*#__PURE__*/ React.createElement(Text, {
93
93
  dimColor: true
94
- }, 'Tip: Create a schedule with "px schedule create ', brainFilter, ' <cron-expression>"')));
94
+ }, 'Tip: Create a schedule with "px schedule create ', brainFilter, ' ', '<cron-expression>"')));
95
95
  }
96
96
  // Sort schedules by creation date (newest first)
97
97
  var sortedSchedules = _to_consumable_array(filteredSchedules).sort(function(a, b) {
@@ -148,25 +148,25 @@ export var ScheduleList = function(param) {
148
148
  }, /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
149
149
  bold: true,
150
150
  color: "cyan"
151
- }, padRight(columns.brainTitle.header, columns.brainTitle.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
151
+ }, padRight(columns.brainTitle.header, columns.brainTitle.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
152
152
  bold: true,
153
153
  color: "cyan"
154
- }, padRight(columns.schedule.header, columns.schedule.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
154
+ }, padRight(columns.schedule.header, columns.schedule.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
155
155
  bold: true,
156
156
  color: "cyan"
157
- }, padRight(columns.status.header, columns.status.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
157
+ }, padRight(columns.status.header, columns.status.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
158
158
  bold: true,
159
159
  color: "cyan"
160
- }, padRight(columns.runAs.header, columns.runAs.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
160
+ }, padRight(columns.runAs.header, columns.runAs.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
161
161
  bold: true,
162
162
  color: "cyan"
163
- }, padRight(columns.timezone.header, columns.timezone.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
163
+ }, padRight(columns.timezone.header, columns.timezone.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
164
164
  bold: true,
165
165
  color: "cyan"
166
- }, padRight(columns.nextRun.header, columns.nextRun.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
166
+ }, padRight(columns.nextRun.header, columns.nextRun.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
167
167
  bold: true,
168
168
  color: "cyan"
169
- }, padRight(columns.created.header, columns.created.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
169
+ }, padRight(columns.created.header, columns.created.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
170
170
  bold: true,
171
171
  color: "cyan"
172
172
  }, padRight(columns.id.header, columns.id.width))), /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
@@ -177,17 +177,17 @@ export var ScheduleList = function(param) {
177
177
  var isOverdue = nextRunDate && nextRunDate.getTime() < Date.now();
178
178
  return /*#__PURE__*/ React.createElement(Box, {
179
179
  key: schedule.id
180
- }, /*#__PURE__*/ React.createElement(Text, null, padRight(truncate(schedule.brainTitle, columns.brainTitle.width), columns.brainTitle.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, null, padRight(truncate(schedule.cronExpression, columns.schedule.width), columns.schedule.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
180
+ }, /*#__PURE__*/ React.createElement(Text, null, padRight(truncate(schedule.brainTitle, columns.brainTitle.width), columns.brainTitle.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, null, padRight(truncate(schedule.cronExpression, columns.schedule.width), columns.schedule.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
181
181
  color: schedule.enabled ? 'green' : 'red'
182
- }, padRight(schedule.enabled ? 'Enabled' : 'Disabled', columns.status.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
182
+ }, padRight(schedule.enabled ? 'Enabled' : 'Disabled', columns.status.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
183
183
  dimColor: true
184
- }, padRight(truncate(schedule.runAsUserName, columns.runAs.width), columns.runAs.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
184
+ }, padRight(truncate(schedule.runAsUserName, columns.runAs.width), columns.runAs.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
185
185
  dimColor: true
186
- }, padRight(truncate(schedule.timezone || 'UTC', columns.timezone.width), columns.timezone.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
186
+ }, padRight(truncate(schedule.timezone || 'UTC', columns.timezone.width), columns.timezone.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
187
187
  color: isOverdue ? 'red' : undefined
188
- }, padRight(nextRunDate ? formatRelativeTime(nextRunDate) : 'N/A', columns.nextRun.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
188
+ }, padRight(nextRunDate ? formatRelativeTime(nextRunDate) : 'N/A', columns.nextRun.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
189
189
  dimColor: true
190
- }, padRight(truncate(formatDate(schedule.createdAt), columns.created.width), columns.created.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
190
+ }, padRight(truncate(formatDate(schedule.createdAt), columns.created.width), columns.created.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
191
191
  dimColor: true
192
192
  }, padRight(schedule.id, columns.id.width)));
193
193
  })));
@@ -71,16 +71,16 @@ export var ScheduleRuns = function(param) {
71
71
  }, /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
72
72
  bold: true,
73
73
  color: "cyan"
74
- }, padRight('Run ID', 38)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
74
+ }, padRight('Run ID', 38)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
75
75
  bold: true,
76
76
  color: "cyan"
77
- }, padRight('Schedule ID', 38)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
77
+ }, padRight('Schedule ID', 38)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
78
78
  bold: true,
79
79
  color: "cyan"
80
- }, padRight('Status', 10)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
80
+ }, padRight('Status', 10)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
81
81
  bold: true,
82
82
  color: "cyan"
83
- }, padRight('Ran At', 20)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
83
+ }, padRight('Ran At', 20)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
84
84
  bold: true,
85
85
  color: "cyan"
86
86
  }, padRight('When', 12))), /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
@@ -88,11 +88,11 @@ export var ScheduleRuns = function(param) {
88
88
  }, '─'.repeat(130))), filteredRuns.map(function(run) {
89
89
  return /*#__PURE__*/ React.createElement(Box, {
90
90
  key: run.id
91
- }, /*#__PURE__*/ React.createElement(Text, null, padRight(run.id, 38)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, null, padRight(run.scheduleId, 38)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
91
+ }, /*#__PURE__*/ React.createElement(Text, null, padRight(run.id, 38)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, null, padRight(run.scheduleId, 38)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
92
92
  color: run.status === 'triggered' ? 'green' : 'red'
93
- }, padRight(run.status, 10)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
93
+ }, padRight(run.status, 10)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
94
94
  dimColor: true
95
- }, padRight(formatDate(run.ranAt), 20)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
95
+ }, padRight(formatDate(run.ranAt), 20)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
96
96
  dimColor: true
97
97
  }, padRight(formatRelativeTime(run.ranAt), 12)));
98
98
  })));
@@ -171,7 +171,7 @@ import { useApiPost } from '../hooks/useApi.js';
171
171
  import * as path from 'path';
172
172
  import * as fs from 'fs';
173
173
  import { parse as parseEnv } from 'dotenv';
174
- export var SecretBulk = function(param) {
174
+ export var SecretsBulk = function(param) {
175
175
  var _param_file = param.file, file = _param_file === void 0 ? '.env' : _param_file, projectDir = param.projectDir;
176
176
  var _useState = _sliced_to_array(useState(null), 2), validationError = _useState[0], setValidationError = _useState[1];
177
177
  var _useState1 = _sliced_to_array(useState(false), 2), completed = _useState1[0], setCompleted = _useState1[1];
@@ -284,7 +284,7 @@ export var SecretBulk = function(param) {
284
284
  marginTop: 1
285
285
  }, /*#__PURE__*/ React.createElement(Text, {
286
286
  dimColor: true
287
- }, 'Tip: Use "px secret list" to view all secrets')));
287
+ }, 'Tip: Use "px secrets list" to view all secrets')));
288
288
  }
289
289
  return null;
290
290
  };
@@ -168,7 +168,7 @@ import React, { useState, useEffect } from 'react';
168
168
  import { Box, Text } from 'ink';
169
169
  import { ErrorComponent } from './error.js';
170
170
  import { useApiPost } from '../hooks/useApi.js';
171
- export var SecretCreate = function(param) {
171
+ export var SecretsCreate = function(param) {
172
172
  var name = param.name, value = param.value;
173
173
  var _useState = _sliced_to_array(useState(false), 2), created = _useState[0], setCreated = _useState[1];
174
174
  var _useState1 = _sliced_to_array(useState(null), 2), secret = _useState1[0], setSecret = _useState1[1];
@@ -239,7 +239,7 @@ export var SecretCreate = function(param) {
239
239
  marginTop: 1
240
240
  }, /*#__PURE__*/ React.createElement(Text, {
241
241
  dimColor: true
242
- }, "Example: px secret create ", name, " --value=my-secret-value")));
242
+ }, "Example: px secrets create ", name, " --value=my-secret-value")));
243
243
  }
244
244
  if (error) {
245
245
  return /*#__PURE__*/ React.createElement(ErrorComponent, {
@@ -264,7 +264,7 @@ export var SecretCreate = function(param) {
264
264
  marginTop: 1
265
265
  }, /*#__PURE__*/ React.createElement(Text, {
266
266
  dimColor: true
267
- }, 'Tip: Use "px secret list" to view all secrets')));
267
+ }, 'Tip: Use "px secrets list" to view all secrets')));
268
268
  }
269
269
  return null;
270
270
  };
@@ -168,7 +168,7 @@ import React, { useState, useEffect } from 'react';
168
168
  import { Box, Text } from 'ink';
169
169
  import { ErrorComponent } from './error.js';
170
170
  import { useApiDelete } from '../hooks/useApi.js';
171
- export var SecretDelete = function(param) {
171
+ export var SecretsDelete = function(param) {
172
172
  var name = param.name;
173
173
  var _useState = _sliced_to_array(useState(false), 2), deleted = _useState[0], setDeleted = _useState[1];
174
174
  var _useApiDelete = useApiDelete('secret'), execute = _useApiDelete.execute, loading = _useApiDelete.loading, error = _useApiDelete.error;
@@ -41,7 +41,7 @@ var formatDate = function(dateStr) {
41
41
  var date = new Date(dateStr);
42
42
  return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
43
43
  };
44
- export var SecretList = function() {
44
+ export var SecretsList = function() {
45
45
  var _useApiGet = useApiGet('/secrets'), data = _useApiGet.data, loading = _useApiGet.loading, error = _useApiGet.error;
46
46
  if (error) {
47
47
  return /*#__PURE__*/ React.createElement(ErrorComponent, {
@@ -58,7 +58,7 @@ export var SecretList = function() {
58
58
  marginTop: 1
59
59
  }, /*#__PURE__*/ React.createElement(Text, {
60
60
  dimColor: true
61
- }, 'Tip: Create a secret with "px secret create <name> --value=<value>"')));
61
+ }, 'Tip: Create a secret with "px secrets create <name> --value=<value>"')));
62
62
  }
63
63
  // Define column widths
64
64
  var columns = {
@@ -91,7 +91,7 @@ export var SecretList = function() {
91
91
  }, /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
92
92
  bold: true,
93
93
  color: "cyan"
94
- }, padRight(columns.name.header, columns.name.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
94
+ }, padRight(columns.name.header, columns.name.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
95
95
  bold: true,
96
96
  color: "cyan"
97
97
  }, padRight(columns.updatedAt.header, columns.updatedAt.width))), /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
@@ -99,7 +99,7 @@ export var SecretList = function() {
99
99
  }, '─'.repeat(totalWidth))), sortedSecrets.map(function(secret) {
100
100
  return /*#__PURE__*/ React.createElement(Box, {
101
101
  key: secret.name
102
- }, /*#__PURE__*/ React.createElement(Text, null, padRight(truncate(secret.name, columns.name.width), columns.name.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
102
+ }, /*#__PURE__*/ React.createElement(Text, null, padRight(truncate(secret.name, columns.name.width), columns.name.width)), /*#__PURE__*/ React.createElement(Text, null, " "), /*#__PURE__*/ React.createElement(Text, {
103
103
  dimColor: true
104
104
  }, padRight(formatDate(secret.updatedAt), columns.updatedAt.width)));
105
105
  })));
@@ -169,12 +169,12 @@ function _ts_generator(thisArg, body) {
169
169
  }
170
170
  }
171
171
  import React, { useState, useEffect, useRef, useCallback } from 'react';
172
- import { Text, Box, useStdout, useInput, useApp } from 'ink';
172
+ import { Text, Box, useInput, useApp } from 'ink';
173
173
  import { apiClient } from '../commands/helpers.js';
174
174
  import { ErrorComponent } from './error.js';
175
175
  import { StateView } from './state-view.js';
176
+ import { useAlternateScreen } from '../hooks/useAlternateScreen.js';
176
177
  export var StoreExplorer = function() {
177
- var write = useStdout().write;
178
178
  var exit = useApp().exit;
179
179
  // Navigation state
180
180
  var _useState = _sliced_to_array(useState('brains'), 2), mode = _useState[0], setMode = _useState[1];
@@ -200,18 +200,7 @@ export var StoreExplorer = function() {
200
200
  // calls through to current state, avoiding stale closure issues
201
201
  // caused by useEffect re-registration timing in ink's useInput.
202
202
  var inputHandlerRef = useRef(function() {});
203
- // Enter alternate screen buffer on mount, exit on unmount
204
- useEffect(function() {
205
- if (process.env.NODE_ENV === 'test') {
206
- return;
207
- }
208
- write('\x1B[?1049h\x1B[2J\x1B[H');
209
- return function() {
210
- write('\x1B[?1049l');
211
- };
212
- }, [
213
- write
214
- ]);
203
+ useAlternateScreen();
215
204
  // Fetch brains list
216
205
  useEffect(function() {
217
206
  if (mode !== 'brains') return;
@@ -562,9 +551,7 @@ export var StoreExplorer = function() {
562
551
  inputHandlerRef.current(input, key);
563
552
  }, []);
564
553
  // Keyboard handling - uses stable callback to avoid stale closure issues
565
- useInput(stableInputHandler, {
566
- isActive: mode !== 'value'
567
- });
554
+ useInput(stableInputHandler);
568
555
  // Adjust selectedIndex if list shrinks
569
556
  useEffect(function() {
570
557
  var listLength = mode === 'brains' ? brains.length : mode === 'keys' ? keys.length : 0;
@@ -45,7 +45,7 @@ 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, useInput, useApp } from 'ink';
48
+ import { Text, Box, useInput, useApp } from 'ink';
49
49
  import { EventSource } from 'eventsource';
50
50
  import { getApiBaseUrl, isApiLocalDevMode, apiClient } from '../commands/helpers.js';
51
51
  import { authenticatedFetch } from '../lib/jwt-auth.js';
@@ -54,9 +54,9 @@ import { useApiDelete } from '../hooks/useApi.js';
54
54
  import { ErrorComponent } from './error.js';
55
55
  import { BrainTopTable } from './brain-top-table.js';
56
56
  import { Watch } from './watch.js';
57
+ import { useAlternateScreen } from '../hooks/useAlternateScreen.js';
57
58
  export var TopNavigator = function(param) {
58
59
  var brainFilter = param.brainFilter;
59
- var write = useStdout().write;
60
60
  var exit = useApp().exit;
61
61
  // Navigation state
62
62
  var _useState = _sliced_to_array(useState('list'), 2), mode = _useState[0], setMode = _useState[1];
@@ -83,21 +83,7 @@ export var TopNavigator = function(param) {
83
83
  var filteredBrains = brainFilter ? runningBrains.filter(function(b) {
84
84
  return b.brainTitle.toLowerCase().includes(brainFilter.toLowerCase());
85
85
  }) : runningBrains;
86
- // Enter alternate screen buffer on mount, exit on unmount
87
- // Skip in test environment to avoid interfering with test output capture
88
- useEffect(function() {
89
- if (process.env.NODE_ENV === 'test') {
90
- return;
91
- }
92
- // Enter alternate screen buffer and clear
93
- write('\x1B[?1049h\x1B[2J\x1B[H');
94
- return function() {
95
- // Exit alternate screen buffer
96
- write('\x1B[?1049l');
97
- };
98
- }, [
99
- write
100
- ]);
86
+ useAlternateScreen();
101
87
  // Update tick every second to refresh duration display (in list mode)
102
88
  useEffect(function() {
103
89
  if (mode !== 'list') return;