@positronic/cli 0.0.2

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 (193) hide show
  1. package/dist/src/cli.js +739 -0
  2. package/dist/src/commands/backend.js +199 -0
  3. package/dist/src/commands/brain.js +446 -0
  4. package/dist/src/commands/brain.test.js +2936 -0
  5. package/dist/src/commands/helpers.js +1315 -0
  6. package/dist/src/commands/helpers.test.js +832 -0
  7. package/dist/src/commands/project-config-manager.js +197 -0
  8. package/dist/src/commands/project.js +130 -0
  9. package/dist/src/commands/project.test.js +1201 -0
  10. package/dist/src/commands/resources.js +272 -0
  11. package/dist/src/commands/resources.test.js +2511 -0
  12. package/dist/src/commands/schedule.js +73 -0
  13. package/dist/src/commands/schedule.test.js +1235 -0
  14. package/dist/src/commands/secret.js +87 -0
  15. package/dist/src/commands/secret.test.d.js +1 -0
  16. package/dist/src/commands/secret.test.js +761 -0
  17. package/dist/src/commands/server.js +816 -0
  18. package/dist/src/commands/server.test.js +1237 -0
  19. package/dist/src/commands/test-utils.js +737 -0
  20. package/dist/src/components/brain-history.js +169 -0
  21. package/dist/src/components/brain-list.js +108 -0
  22. package/dist/src/components/brain-rerun.js +313 -0
  23. package/dist/src/components/brain-show.js +65 -0
  24. package/dist/src/components/error.js +19 -0
  25. package/dist/src/components/project-add.js +95 -0
  26. package/dist/src/components/project-create.js +276 -0
  27. package/dist/src/components/project-list.js +88 -0
  28. package/dist/src/components/project-remove.js +91 -0
  29. package/dist/src/components/project-select.js +224 -0
  30. package/dist/src/components/project-show.js +41 -0
  31. package/dist/src/components/resource-clear.js +152 -0
  32. package/dist/src/components/resource-delete.js +189 -0
  33. package/dist/src/components/resource-list.js +174 -0
  34. package/dist/src/components/resource-sync.js +386 -0
  35. package/dist/src/components/resource-types.js +243 -0
  36. package/dist/src/components/resource-upload.js +366 -0
  37. package/dist/src/components/schedule-create.js +259 -0
  38. package/dist/src/components/schedule-delete.js +161 -0
  39. package/dist/src/components/schedule-list.js +176 -0
  40. package/dist/src/components/schedule-runs.js +103 -0
  41. package/dist/src/components/secret-bulk.js +262 -0
  42. package/dist/src/components/secret-create.js +199 -0
  43. package/dist/src/components/secret-delete.js +190 -0
  44. package/dist/src/components/secret-list.js +190 -0
  45. package/dist/src/components/secret-sync.js +303 -0
  46. package/dist/src/components/watch.js +184 -0
  47. package/dist/src/hooks/useApi.js +512 -0
  48. package/dist/src/positronic.js +33 -0
  49. package/dist/src/test/mock-api-client.js +371 -0
  50. package/dist/src/test/test-dev-server.js +1376 -0
  51. package/dist/types/cli.d.ts +9 -0
  52. package/dist/types/cli.d.ts.map +1 -0
  53. package/dist/types/commands/backend.d.ts +6 -0
  54. package/dist/types/commands/backend.d.ts.map +1 -0
  55. package/dist/types/commands/brain.d.ts +35 -0
  56. package/dist/types/commands/brain.d.ts.map +1 -0
  57. package/dist/types/commands/helpers.d.ts +55 -0
  58. package/dist/types/commands/helpers.d.ts.map +1 -0
  59. package/dist/types/commands/project-config-manager.d.ts +37 -0
  60. package/dist/types/commands/project-config-manager.d.ts.map +1 -0
  61. package/dist/types/commands/project.d.ts +55 -0
  62. package/dist/types/commands/project.d.ts.map +1 -0
  63. package/dist/types/commands/resources.d.ts +13 -0
  64. package/dist/types/commands/resources.d.ts.map +1 -0
  65. package/dist/types/commands/schedule.d.ts +27 -0
  66. package/dist/types/commands/schedule.d.ts.map +1 -0
  67. package/dist/types/commands/secret.d.ts +23 -0
  68. package/dist/types/commands/secret.d.ts.map +1 -0
  69. package/dist/types/commands/server.d.ts +12 -0
  70. package/dist/types/commands/server.d.ts.map +1 -0
  71. package/dist/types/commands/test-utils.d.ts +45 -0
  72. package/dist/types/commands/test-utils.d.ts.map +1 -0
  73. package/dist/types/components/brain-history.d.ts +7 -0
  74. package/dist/types/components/brain-history.d.ts.map +1 -0
  75. package/dist/types/components/brain-list.d.ts +2 -0
  76. package/dist/types/components/brain-list.d.ts.map +1 -0
  77. package/dist/types/components/brain-rerun.d.ts +9 -0
  78. package/dist/types/components/brain-rerun.d.ts.map +1 -0
  79. package/dist/types/components/brain-show.d.ts +6 -0
  80. package/dist/types/components/brain-show.d.ts.map +1 -0
  81. package/dist/types/components/error.d.ts +10 -0
  82. package/dist/types/components/error.d.ts.map +1 -0
  83. package/dist/types/components/project-add.d.ts +9 -0
  84. package/dist/types/components/project-add.d.ts.map +1 -0
  85. package/dist/types/components/project-create.d.ts +6 -0
  86. package/dist/types/components/project-create.d.ts.map +1 -0
  87. package/dist/types/components/project-list.d.ts +7 -0
  88. package/dist/types/components/project-list.d.ts.map +1 -0
  89. package/dist/types/components/project-remove.d.ts +8 -0
  90. package/dist/types/components/project-remove.d.ts.map +1 -0
  91. package/dist/types/components/project-select.d.ts +8 -0
  92. package/dist/types/components/project-select.d.ts.map +1 -0
  93. package/dist/types/components/project-show.d.ts +7 -0
  94. package/dist/types/components/project-show.d.ts.map +1 -0
  95. package/dist/types/components/resource-clear.d.ts +2 -0
  96. package/dist/types/components/resource-clear.d.ts.map +1 -0
  97. package/dist/types/components/resource-delete.d.ts +9 -0
  98. package/dist/types/components/resource-delete.d.ts.map +1 -0
  99. package/dist/types/components/resource-list.d.ts +2 -0
  100. package/dist/types/components/resource-list.d.ts.map +1 -0
  101. package/dist/types/components/resource-sync.d.ts +8 -0
  102. package/dist/types/components/resource-sync.d.ts.map +1 -0
  103. package/dist/types/components/resource-types.d.ts +7 -0
  104. package/dist/types/components/resource-types.d.ts.map +1 -0
  105. package/dist/types/components/resource-upload.d.ts +8 -0
  106. package/dist/types/components/resource-upload.d.ts.map +1 -0
  107. package/dist/types/components/schedule-create.d.ts +7 -0
  108. package/dist/types/components/schedule-create.d.ts.map +1 -0
  109. package/dist/types/components/schedule-delete.d.ts +7 -0
  110. package/dist/types/components/schedule-delete.d.ts.map +1 -0
  111. package/dist/types/components/schedule-list.d.ts +6 -0
  112. package/dist/types/components/schedule-list.d.ts.map +1 -0
  113. package/dist/types/components/schedule-runs.d.ts +8 -0
  114. package/dist/types/components/schedule-runs.d.ts.map +1 -0
  115. package/dist/types/components/secret-bulk.d.ts +8 -0
  116. package/dist/types/components/secret-bulk.d.ts.map +1 -0
  117. package/dist/types/components/secret-create.d.ts +9 -0
  118. package/dist/types/components/secret-create.d.ts.map +1 -0
  119. package/dist/types/components/secret-delete.d.ts +8 -0
  120. package/dist/types/components/secret-delete.d.ts.map +1 -0
  121. package/dist/types/components/secret-list.d.ts +7 -0
  122. package/dist/types/components/secret-list.d.ts.map +1 -0
  123. package/dist/types/components/secret-sync.d.ts +9 -0
  124. package/dist/types/components/secret-sync.d.ts.map +1 -0
  125. package/dist/types/components/watch.d.ts +7 -0
  126. package/dist/types/components/watch.d.ts.map +1 -0
  127. package/dist/types/hooks/useApi.d.ts +29 -0
  128. package/dist/types/hooks/useApi.d.ts.map +1 -0
  129. package/dist/types/positronic.d.ts +3 -0
  130. package/dist/types/positronic.d.ts.map +1 -0
  131. package/dist/types/test/mock-api-client.d.ts +25 -0
  132. package/dist/types/test/mock-api-client.d.ts.map +1 -0
  133. package/dist/types/test/test-dev-server.d.ts +129 -0
  134. package/dist/types/test/test-dev-server.d.ts.map +1 -0
  135. package/package.json +37 -0
  136. package/src/cli.ts +981 -0
  137. package/src/commands/backend.ts +63 -0
  138. package/src/commands/brain.test.ts +1004 -0
  139. package/src/commands/brain.ts +215 -0
  140. package/src/commands/helpers.test.ts +487 -0
  141. package/src/commands/helpers.ts +870 -0
  142. package/src/commands/project-config-manager.ts +152 -0
  143. package/src/commands/project.test.ts +502 -0
  144. package/src/commands/project.ts +109 -0
  145. package/src/commands/resources.test.ts +1052 -0
  146. package/src/commands/resources.ts +97 -0
  147. package/src/commands/schedule.test.ts +481 -0
  148. package/src/commands/schedule.ts +65 -0
  149. package/src/commands/secret.test.ts +210 -0
  150. package/src/commands/secret.ts +50 -0
  151. package/src/commands/server.test.ts +493 -0
  152. package/src/commands/server.ts +353 -0
  153. package/src/commands/test-utils.ts +324 -0
  154. package/src/components/brain-history.tsx +198 -0
  155. package/src/components/brain-list.tsx +105 -0
  156. package/src/components/brain-rerun.tsx +111 -0
  157. package/src/components/brain-show.tsx +92 -0
  158. package/src/components/error.tsx +24 -0
  159. package/src/components/project-add.tsx +59 -0
  160. package/src/components/project-create.tsx +83 -0
  161. package/src/components/project-list.tsx +83 -0
  162. package/src/components/project-remove.tsx +55 -0
  163. package/src/components/project-select.tsx +200 -0
  164. package/src/components/project-show.tsx +58 -0
  165. package/src/components/resource-clear.tsx +127 -0
  166. package/src/components/resource-delete.tsx +160 -0
  167. package/src/components/resource-list.tsx +177 -0
  168. package/src/components/resource-sync.tsx +170 -0
  169. package/src/components/resource-types.tsx +55 -0
  170. package/src/components/resource-upload.tsx +182 -0
  171. package/src/components/schedule-create.tsx +90 -0
  172. package/src/components/schedule-delete.tsx +116 -0
  173. package/src/components/schedule-list.tsx +186 -0
  174. package/src/components/schedule-runs.tsx +151 -0
  175. package/src/components/secret-bulk.tsx +79 -0
  176. package/src/components/secret-create.tsx +49 -0
  177. package/src/components/secret-delete.tsx +41 -0
  178. package/src/components/secret-list.tsx +41 -0
  179. package/src/components/watch.tsx +155 -0
  180. package/src/hooks/useApi.ts +183 -0
  181. package/src/positronic.ts +40 -0
  182. package/src/test/data/resources/config.json +1 -0
  183. package/src/test/data/resources/data/config.json +1 -0
  184. package/src/test/data/resources/data/logo.png +2 -0
  185. package/src/test/data/resources/docs/api.md +3 -0
  186. package/src/test/data/resources/docs/readme.md +3 -0
  187. package/src/test/data/resources/example.md +3 -0
  188. package/src/test/data/resources/file with spaces.txt +1 -0
  189. package/src/test/data/resources/readme.md +3 -0
  190. package/src/test/data/resources/test.txt +1 -0
  191. package/src/test/mock-api-client.ts +145 -0
  192. package/src/test/test-dev-server.ts +1003 -0
  193. package/tsconfig.json +11 -0
@@ -0,0 +1,739 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
+ try {
3
+ var info = gen[key](arg);
4
+ var value = info.value;
5
+ } catch (error) {
6
+ reject(error);
7
+ return;
8
+ }
9
+ if (info.done) {
10
+ resolve(value);
11
+ } else {
12
+ Promise.resolve(value).then(_next, _throw);
13
+ }
14
+ }
15
+ function _async_to_generator(fn) {
16
+ return function() {
17
+ var self = this, args = arguments;
18
+ return new Promise(function(resolve, reject) {
19
+ var gen = fn.apply(self, args);
20
+ function _next(value) {
21
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
22
+ }
23
+ function _throw(err) {
24
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
25
+ }
26
+ _next(undefined);
27
+ });
28
+ };
29
+ }
30
+ function _instanceof(left, right) {
31
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
32
+ return !!right[Symbol.hasInstance](left);
33
+ } else {
34
+ return left instanceof right;
35
+ }
36
+ }
37
+ function _ts_generator(thisArg, body) {
38
+ var f, y, t, _ = {
39
+ label: 0,
40
+ sent: function() {
41
+ if (t[0] & 1) throw t[1];
42
+ return t[1];
43
+ },
44
+ trys: [],
45
+ ops: []
46
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
47
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
48
+ return this;
49
+ }), g;
50
+ function verb(n) {
51
+ return function(v) {
52
+ return step([
53
+ n,
54
+ v
55
+ ]);
56
+ };
57
+ }
58
+ function step(op) {
59
+ if (f) throw new TypeError("Generator is already executing.");
60
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
61
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
62
+ if (y = 0, t) op = [
63
+ op[0] & 2,
64
+ t.value
65
+ ];
66
+ switch(op[0]){
67
+ case 0:
68
+ case 1:
69
+ t = op;
70
+ break;
71
+ case 4:
72
+ _.label++;
73
+ return {
74
+ value: op[1],
75
+ done: false
76
+ };
77
+ case 5:
78
+ _.label++;
79
+ y = op[1];
80
+ op = [
81
+ 0
82
+ ];
83
+ continue;
84
+ case 7:
85
+ op = _.ops.pop();
86
+ _.trys.pop();
87
+ continue;
88
+ default:
89
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
90
+ _ = 0;
91
+ continue;
92
+ }
93
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
94
+ _.label = op[1];
95
+ break;
96
+ }
97
+ if (op[0] === 6 && _.label < t[1]) {
98
+ _.label = t[1];
99
+ t = op;
100
+ break;
101
+ }
102
+ if (t && _.label < t[2]) {
103
+ _.label = t[2];
104
+ _.ops.push(op);
105
+ break;
106
+ }
107
+ if (t[2]) _.ops.pop();
108
+ _.trys.pop();
109
+ continue;
110
+ }
111
+ op = body.call(thisArg, _);
112
+ } catch (e) {
113
+ op = [
114
+ 6,
115
+ e
116
+ ];
117
+ y = 0;
118
+ } finally{
119
+ f = t = 0;
120
+ }
121
+ if (op[0] & 5) throw op[1];
122
+ return {
123
+ value: op[0] ? op[1] : void 0,
124
+ done: true
125
+ };
126
+ }
127
+ }
128
+ import yargs from 'yargs';
129
+ import { hideBin } from 'yargs/helpers';
130
+ import { ProjectCommand } from './commands/project.js';
131
+ import { ServerCommand } from './commands/server.js';
132
+ import { BrainCommand } from './commands/brain.js';
133
+ import { ResourcesCommand } from './commands/resources.js';
134
+ import { ScheduleCommand } from './commands/schedule.js';
135
+ import { SecretCommand } from './commands/secret.js';
136
+ export function buildCli(options) {
137
+ var _options_argv = options.argv, argv = _options_argv === void 0 ? hideBin(process.argv) : _options_argv, server = options.server, _options_exitProcess = options.exitProcess, exitProcess = _options_exitProcess === void 0 ? false : _options_exitProcess, render = options.render;
138
+ var isLocalDevMode = server !== undefined;
139
+ // Instantiate command classes, passing the determined mode and path
140
+ var projectCommand = new ProjectCommand();
141
+ var brainCommand = new BrainCommand();
142
+ var scheduleCommand = new ScheduleCommand();
143
+ var secretCommand = new SecretCommand(server);
144
+ // Main CLI definition
145
+ var cli = yargs(argv).scriptName('positronic').usage('Usage: $0 <command> [options]').version().alias('v', 'version').help('h').alias('h', 'help').wrap(null).strictCommands().exitProcess(exitProcess);
146
+ // --- Project Management Commands (Global Mode Only) ---
147
+ cli = cli.command('project', 'Manage your Positronic projects\n', function(yargsProject) {
148
+ if (!isLocalDevMode) {
149
+ yargsProject.command('new <name>', 'Create a new Positronic project directory', function(yargsNew) {
150
+ return yargsNew.positional('name', {
151
+ describe: 'Name of the new project directory to create',
152
+ type: 'string',
153
+ demandOption: true
154
+ });
155
+ }, function(argv) {
156
+ var element = projectCommand.create(argv);
157
+ render(element);
158
+ });
159
+ }
160
+ yargsProject.command('add <name>', 'Add a project to your list of projects', function(yargsAdd) {
161
+ return yargsAdd.positional('name', {
162
+ describe: 'Name for the project',
163
+ type: 'string',
164
+ demandOption: true
165
+ }).option('url', {
166
+ describe: 'Project API URL',
167
+ type: 'string',
168
+ demandOption: true
169
+ }).example('$0 project add my-project --url https://api.my-project.positronic.sh', 'Add a project configuration');
170
+ }, function(argv) {
171
+ var element = projectCommand.add(argv);
172
+ render(element);
173
+ }).command('select [name]', 'Switch the active project', function(yargsSelect) {
174
+ return yargsSelect.positional('name', {
175
+ describe: 'Project name to select',
176
+ type: 'string'
177
+ }).example('$0 project select my-project', 'Switch the active project').example('$0 project select', 'Interactive project selection');
178
+ }, function(argv) {
179
+ var element = projectCommand.select(argv);
180
+ render(element);
181
+ }).command('list', 'List all of your Positronic projects', function() {}, function() {
182
+ var element = projectCommand.list();
183
+ render(element);
184
+ }).command('show', 'Display your currently selected project', function() {}, function() {
185
+ var element = projectCommand.show();
186
+ render(element);
187
+ }).command('rm <name>', 'Remove a project from your list of projects', function(yargsRm) {
188
+ return yargsRm.positional('name', {
189
+ describe: 'Name of the project to remove',
190
+ type: 'string',
191
+ demandOption: true
192
+ }).example('$0 project rm my-project', 'Remove a project configuration');
193
+ }, function(argv) {
194
+ var element = projectCommand.remove(argv);
195
+ render(element);
196
+ }).demandCommand(1, 'You need to specify a project command (add, select, list, show, rm) in Local Dev Mode.');
197
+ return yargsProject;
198
+ });
199
+ // --- Add the 'new' command alias (Global Mode Only) ---
200
+ if (!isLocalDevMode) {
201
+ cli = cli.command('new <name>', 'Alias for `project new`. Create a new Positronic project directory.\n', function(yargsNewAlias) {
202
+ return yargsNewAlias.positional('name', {
203
+ describe: 'Name of the new project directory to create',
204
+ type: 'string',
205
+ demandOption: true
206
+ });
207
+ }, function(argv) {
208
+ var element = projectCommand.create(argv);
209
+ render(element);
210
+ });
211
+ }
212
+ // --- Add the Server Command ---
213
+ // The server command should only be available in local dev mode;
214
+ // Wrap its registration in the check
215
+ if (isLocalDevMode) {
216
+ var serverCommand = new ServerCommand(server);
217
+ cli = cli.command([
218
+ 'server',
219
+ 's'
220
+ ], 'Start the local development server for the current project', function(yargsServer) {
221
+ return yargsServer.option('force', {
222
+ describe: 'Force regeneration of the .positronic server directory',
223
+ type: 'boolean',
224
+ default: false
225
+ }).option('port', {
226
+ describe: 'Port number for the server to listen on',
227
+ type: 'number',
228
+ alias: 'p'
229
+ }).option('log-file', {
230
+ describe: 'File to redirect server output to (for AI agents)',
231
+ type: 'string',
232
+ alias: 'l'
233
+ }).option('d', {
234
+ describe: 'Run server in detached/background mode',
235
+ type: 'boolean',
236
+ default: false
237
+ }).option('k', {
238
+ describe: 'Kill the default background server',
239
+ type: 'boolean',
240
+ default: false
241
+ });
242
+ }, function(argv) {
243
+ return serverCommand.handle(argv);
244
+ });
245
+ // Add deploy command (only in local dev mode)
246
+ cli = cli.command('deploy', 'Deploy the project to production', function() {}, function() {
247
+ return _async_to_generator(function() {
248
+ var error;
249
+ return _ts_generator(this, function(_state) {
250
+ switch(_state.label){
251
+ case 0:
252
+ _state.trys.push([
253
+ 0,
254
+ 2,
255
+ ,
256
+ 3
257
+ ]);
258
+ // Deploy
259
+ return [
260
+ 4,
261
+ server.deploy()
262
+ ];
263
+ case 1:
264
+ _state.sent();
265
+ return [
266
+ 3,
267
+ 3
268
+ ];
269
+ case 2:
270
+ error = _state.sent();
271
+ console.error('Deployment failed:', _instanceof(error, Error) ? error.message : String(error));
272
+ process.exit(1);
273
+ return [
274
+ 3,
275
+ 3
276
+ ];
277
+ case 3:
278
+ return [
279
+ 2
280
+ ];
281
+ }
282
+ });
283
+ })();
284
+ });
285
+ }
286
+ // --- List Brains Command ---
287
+ cli = cli.command('list', 'List all brains in the active project\n', function() {}, function(argv) {
288
+ var element = brainCommand.list(argv);
289
+ render(element);
290
+ });
291
+ // --- Brain History Command ---
292
+ cli = cli.command('history <name>', 'List recent runs of a specific brain\n', function(yargsHistory) {
293
+ return yargsHistory.positional('name', {
294
+ describe: 'Name of the brain',
295
+ type: 'string',
296
+ demandOption: true
297
+ }).option('limit', {
298
+ describe: 'Maximum number of runs to show',
299
+ type: 'number',
300
+ default: 10
301
+ }).example('$0 history my-brain', 'List recent runs for my-brain').example('$0 history my-brain --limit=20', 'List more recent runs');
302
+ }, function(argv) {
303
+ var element = brainCommand.history(argv);
304
+ render(element);
305
+ });
306
+ // --- Show Brain Command ---
307
+ cli = cli.command('show <name>', 'List all steps and other details for the brain\n', function(yargsShow) {
308
+ return yargsShow.positional('name', {
309
+ describe: 'Name of the brain',
310
+ type: 'string',
311
+ demandOption: true
312
+ });
313
+ }, function(argv) {
314
+ var element = brainCommand.show(argv);
315
+ render(element);
316
+ });
317
+ // --- Rerun Brain Command ---
318
+ cli = cli.command('rerun <name> [run-id]', 'Rerun an existing brain run\n', function(yargsRerun) {
319
+ return yargsRerun.positional('name', {
320
+ describe: 'Name of the brain',
321
+ type: 'string',
322
+ demandOption: true
323
+ }).positional('run-id', {
324
+ describe: 'ID of the brain run to rerun (defaults to the most recent run)',
325
+ type: 'string'
326
+ }).option('starts-at', {
327
+ describe: 'Step number to start execution from',
328
+ type: 'number'
329
+ }).alias('starts-at', 's').option('stops-after', {
330
+ describe: 'Step number to stop execution after',
331
+ type: 'number'
332
+ }).alias('stops-after', 'e').example('$0 rerun my-brain', 'Rerun the most recent execution of my-brain').example('$0 rerun my-brain abc123', 'Rerun a specific brain run').example('$0 rerun my-brain --starts-at=3', 'Rerun from step 3').example('$0 rerun my-brain --stops-after=5', 'Rerun and stop after step 5').example('$0 rerun my-brain --starts-at=3 --stops-after=5', 'Rerun steps 3 through 5');
333
+ }, function(argv) {
334
+ var element = brainCommand.rerun(argv);
335
+ render(element);
336
+ });
337
+ // --- Run Brain Command ---
338
+ cli = cli.command('run <name>', 'Run a brain and optionally watch its execution\n', function(yargsRun) {
339
+ return yargsRun.positional('name', {
340
+ describe: 'Name of the brain',
341
+ type: 'string',
342
+ demandOption: true
343
+ }).option('watch', {
344
+ describe: 'Watch the brain run immediately after starting',
345
+ type: 'boolean',
346
+ alias: 'w',
347
+ default: false
348
+ }).example('$0 run my-brain', 'Run a brain by name').example('$0 run my-brain --watch', 'Run a brain and watch its execution');
349
+ }, function(argv) {
350
+ return _async_to_generator(function() {
351
+ var element;
352
+ return _ts_generator(this, function(_state) {
353
+ switch(_state.label){
354
+ case 0:
355
+ return [
356
+ 4,
357
+ brainCommand.run(argv)
358
+ ];
359
+ case 1:
360
+ element = _state.sent();
361
+ if (element) {
362
+ render(element);
363
+ }
364
+ return [
365
+ 2
366
+ ];
367
+ }
368
+ });
369
+ })();
370
+ });
371
+ // --- Watch Brain Run Command ---
372
+ cli = cli.command('watch [name]', 'Watch a brain run: latest by name (default) or specific by ID\n', function(yargsWatch) {
373
+ return yargsWatch.positional('name', {
374
+ describe: 'Name of the brain to watch (watches the most recent run)',
375
+ type: 'string'
376
+ }).option('run-id', {
377
+ describe: 'ID of the specific brain run to watch',
378
+ type: 'string',
379
+ alias: 'id'
380
+ }).conflicts('name', 'run-id').check(function(argv) {
381
+ if (!argv.name && !argv.runId) {
382
+ throw new Error('You must provide either a brain name or a --run-id.');
383
+ }
384
+ return true;
385
+ }).example('$0 watch my-brain', "Watch the latest run of the brain named 'my-brain'").example('$0 watch --run-id abc123def', 'Watch a specific brain run by its ID');
386
+ }, function(argv) {
387
+ return _async_to_generator(function() {
388
+ var element;
389
+ return _ts_generator(this, function(_state) {
390
+ switch(_state.label){
391
+ case 0:
392
+ return [
393
+ 4,
394
+ brainCommand.watch(argv)
395
+ ];
396
+ case 1:
397
+ element = _state.sent();
398
+ if (element) {
399
+ render(element);
400
+ }
401
+ return [
402
+ 2
403
+ ];
404
+ }
405
+ });
406
+ })();
407
+ });
408
+ // --- Brain Commands ---
409
+ cli = cli.command('brain', 'Manage your brains\n', function(yargsBrain) {
410
+ yargsBrain.command('list', 'List all brains in the active project\n', function() {}, function(argv) {
411
+ var element = brainCommand.list(argv);
412
+ render(element);
413
+ }).command('history <name>', 'List recent runs of a specific brain\n', function(yargsHistory) {
414
+ return yargsHistory.positional('name', {
415
+ describe: 'Name of the brain',
416
+ type: 'string',
417
+ demandOption: true
418
+ }).option('limit', {
419
+ describe: 'Maximum number of runs to show',
420
+ type: 'number',
421
+ default: 10
422
+ }).example('$0 brain history my-brain', 'List recent runs for my-brain').example('$0 brain history my-brain --limit=20', 'List more recent runs');
423
+ }, function(argv) {
424
+ var element = brainCommand.history(argv);
425
+ render(element);
426
+ }).command('show <name>', 'List all steps and other details for the brain\n', function(yargsShow) {
427
+ return yargsShow.positional('name', {
428
+ describe: 'Name of the brain',
429
+ type: 'string',
430
+ demandOption: true
431
+ });
432
+ }, function(argv) {
433
+ var element = brainCommand.show(argv);
434
+ render(element);
435
+ }).command('rerun <name> [run-id]', 'Rerun an existing brain run\n', function(yargsRerun) {
436
+ return yargsRerun.positional('name', {
437
+ describe: 'Name of the brain',
438
+ type: 'string',
439
+ demandOption: true
440
+ }).positional('run-id', {
441
+ describe: 'ID of the brain run to rerun (defaults to the most recent run)',
442
+ type: 'string'
443
+ }).option('starts-at', {
444
+ describe: 'Step number to start execution from',
445
+ type: 'number'
446
+ }).alias('starts-at', 's').option('stops-after', {
447
+ describe: 'Step number to stop execution after',
448
+ type: 'number'
449
+ }).alias('stops-after', 'e').example('$0 brain rerun my-brain', 'Rerun the most recent execution of my-brain').example('$0 brain rerun my-brain abc123', 'Rerun a specific brain run').example('$0 brain rerun my-brain --starts-at=3', 'Rerun from step 3').example('$0 brain rerun my-brain --stops-after=5', 'Rerun and stop after step 5').example('$0 brain rerun my-brain --starts-at=3 --stops-after=5', 'Rerun steps 3 through 5');
450
+ }, function(argv) {
451
+ var element = brainCommand.rerun(argv);
452
+ render(element);
453
+ }).command('run <name>', 'Run a brain and optionally watch its execution\n', function(yargsRun) {
454
+ return yargsRun.positional('name', {
455
+ describe: 'Name of the brain',
456
+ type: 'string',
457
+ demandOption: true
458
+ }).option('watch', {
459
+ describe: 'Watch the brain run immediately after starting',
460
+ type: 'boolean',
461
+ alias: 'w',
462
+ default: false
463
+ }).example('$0 brain run my-brain', 'Run a brain by name').example('$0 brain run my-brain --watch', 'Run a brain and watch its execution');
464
+ }, function(argv) {
465
+ return _async_to_generator(function() {
466
+ var element;
467
+ return _ts_generator(this, function(_state) {
468
+ switch(_state.label){
469
+ case 0:
470
+ return [
471
+ 4,
472
+ brainCommand.run(argv)
473
+ ];
474
+ case 1:
475
+ element = _state.sent();
476
+ if (element) {
477
+ render(element);
478
+ }
479
+ return [
480
+ 2
481
+ ];
482
+ }
483
+ });
484
+ })();
485
+ }).command('watch [name]', 'Watch a brain run: latest by name (default) or specific by ID\n', function(yargsWatch) {
486
+ return yargsWatch.positional('name', {
487
+ describe: 'Name of the brain to watch (watches the most recent run)',
488
+ type: 'string'
489
+ }).option('run-id', {
490
+ describe: 'ID of the specific brain run to watch',
491
+ type: 'string',
492
+ alias: 'id'
493
+ }).conflicts('name', 'run-id').check(function(argv) {
494
+ if (!argv.name && !argv.runId) {
495
+ throw new Error('You must provide either a brain name or a --run-id.');
496
+ }
497
+ return true;
498
+ }).example('$0 brain watch my-brain', "Watch the latest run of the brain named 'my-brain'").example('$0 brain watch --run-id abc123def', 'Watch a specific brain run by its ID');
499
+ }, function(argv) {
500
+ return _async_to_generator(function() {
501
+ var element;
502
+ return _ts_generator(this, function(_state) {
503
+ switch(_state.label){
504
+ case 0:
505
+ return [
506
+ 4,
507
+ brainCommand.watch(argv)
508
+ ];
509
+ case 1:
510
+ element = _state.sent();
511
+ if (element) {
512
+ render(element);
513
+ }
514
+ return [
515
+ 2
516
+ ];
517
+ }
518
+ });
519
+ })();
520
+ }).demandCommand(1, 'You need to specify a brain command (list, history, show, rerun, run, watch).');
521
+ return yargsBrain;
522
+ });
523
+ // --- Resource Management Commands ---
524
+ cli = cli.command('resources', 'Resources are any data that can be used in your brains, agents, and prompts. They can be text or binaries.\n', function(yargsResource) {
525
+ var resourcesCommand = new ResourcesCommand(server);
526
+ yargsResource.command('list', 'List all resources in the active project\n', function(yargsListCmd) {
527
+ return yargsListCmd.example('$0 resources list', 'List all resources in the active project');
528
+ }, function() {
529
+ var element = resourcesCommand.list();
530
+ render(element);
531
+ });
532
+ // Command available ONLY in Local Dev Mode
533
+ yargsResource.command('sync', 'Sync local resources folder with the server so they are available to brains when they run\n', function(yargsSyncCmd) {
534
+ return yargsSyncCmd.example('$0 resources sync', 'Upload new or modified resources to the server');
535
+ }, function() {
536
+ var element = resourcesCommand.sync();
537
+ render(element);
538
+ });
539
+ yargsResource.command('types', 'Generate TypeScript type definitions for resources\n', function(yargsTypesCmd) {
540
+ return yargsTypesCmd.example('$0 resources types', 'Generate a resources.d.ts file with type definitions for all resources');
541
+ }, function() {
542
+ var element = resourcesCommand.types();
543
+ render(element);
544
+ });
545
+ yargsResource.command('clear', 'Delete ALL resources from the server (development only)\n', function(yargsClearCmd) {
546
+ return yargsClearCmd.example('$0 resources clear', 'Delete all resources from the server');
547
+ }, function() {
548
+ return _async_to_generator(function() {
549
+ var element;
550
+ return _ts_generator(this, function(_state) {
551
+ switch(_state.label){
552
+ case 0:
553
+ return [
554
+ 4,
555
+ resourcesCommand.clear()
556
+ ];
557
+ case 1:
558
+ element = _state.sent();
559
+ if (element) {
560
+ render(element);
561
+ }
562
+ return [
563
+ 2
564
+ ];
565
+ }
566
+ });
567
+ })();
568
+ });
569
+ // Upload/delete command available in both dev and production modes
570
+ yargsResource.command('upload <file>', 'Upload a file as a resource, or delete with -d flag\n', function(yargsUploadCmd) {
571
+ return yargsUploadCmd.positional('file', {
572
+ describe: 'File path to upload, or resource key when using -d flag',
573
+ type: 'string',
574
+ demandOption: true
575
+ }).option('key', {
576
+ describe: 'Custom key/path for the resource (defaults to filename)',
577
+ type: 'string',
578
+ alias: 'k'
579
+ }).option('delete', {
580
+ describe: 'Delete the resource instead of uploading',
581
+ type: 'boolean',
582
+ alias: 'd',
583
+ default: false
584
+ }).option('force', {
585
+ describe: 'Skip confirmation prompts (use with --delete)',
586
+ type: 'boolean',
587
+ alias: 'f',
588
+ default: false
589
+ }).example('$0 resources upload video.mp4', 'Upload a video file').example('$0 resources upload /path/to/large-file.zip --key archive/backup.zip', 'Upload with custom resource key').example('$0 resources upload -d video.mp4', 'Delete the resource with key "video.mp4"').example('$0 resources upload -d archive/backup.zip', 'Delete a resource with a nested key').example('$0 resources upload -d -f video.mp4', 'Delete a resource without confirmation');
590
+ }, function(argv) {
591
+ if (argv.delete) {
592
+ var element = resourcesCommand.delete(argv.file, argv.force);
593
+ render(element);
594
+ } else {
595
+ var element1 = resourcesCommand.upload(argv.file, argv.key);
596
+ render(element1);
597
+ }
598
+ });
599
+ return yargsResource.demandCommand(1, 'You need to specify a resources command');
600
+ });
601
+ // --- Schedule Management Commands ---
602
+ cli = cli.command('schedule', 'Schedule brain runs to execute automatically on a cron schedule\n', function(yargsSchedule) {
603
+ // Add top-level options for list and delete
604
+ yargsSchedule.option('list', {
605
+ describe: 'List all scheduled brain runs',
606
+ type: 'boolean',
607
+ alias: 'l'
608
+ }).option('delete', {
609
+ describe: 'Delete a schedule by ID',
610
+ type: 'string',
611
+ alias: 'd'
612
+ }).option('brain', {
613
+ describe: 'Filter schedules by brain name (used with -l)',
614
+ type: 'string',
615
+ alias: 'b'
616
+ }).option('force', {
617
+ describe: 'Skip confirmation prompt (used with -d)',
618
+ type: 'boolean',
619
+ alias: 'f',
620
+ default: false
621
+ }).example('$0 schedule -l', 'List all schedules').example('$0 schedule -l --brain my-brain', 'List schedules for a specific brain').example('$0 schedule -d abc123', 'Delete schedule with ID abc123').example('$0 schedule -d abc123 --force', 'Delete without confirmation').check(function(argv) {
622
+ // Count how many operations are specified
623
+ var operations = [
624
+ argv.list,
625
+ argv.delete,
626
+ argv._.includes('create') || argv._.includes('c'),
627
+ argv._.includes('runs')
628
+ ].filter(Boolean).length;
629
+ if (operations === 0) {
630
+ throw new Error('You must specify an operation: create, -l (list), -d (delete), or runs');
631
+ }
632
+ if (operations > 1) {
633
+ throw new Error('You can only specify one operation at a time');
634
+ }
635
+ return true;
636
+ });
637
+ // Handle top-level list/delete options
638
+ yargsSchedule.middleware(function(argv) {
639
+ // If -l flag is used, call list command
640
+ if (argv.list) {
641
+ var element = scheduleCommand.list({
642
+ brain: argv.brain
643
+ });
644
+ render(element);
645
+ // Exit after completion to prevent further command processing
646
+ process.exit(0);
647
+ }
648
+ // If -d flag is used, call delete command
649
+ if (argv.delete) {
650
+ var element1 = scheduleCommand.delete({
651
+ scheduleId: argv.delete,
652
+ force: argv.force
653
+ });
654
+ render(element1);
655
+ // Exit after completion to prevent further command processing
656
+ process.exit(0);
657
+ }
658
+ }, true);
659
+ yargsSchedule.command([
660
+ 'create <brain-name> <cron-expression>',
661
+ 'c <brain-name> <cron-expression>'
662
+ ], 'Create a new schedule for a brain\n', function(yargsCreate) {
663
+ return yargsCreate.positional('brain-name', {
664
+ describe: 'Name of the brain to schedule',
665
+ type: 'string',
666
+ demandOption: true
667
+ }).positional('cron-expression', {
668
+ describe: 'Cron expression for the schedule (e.g., "0 3 * * *" for daily at 3am)',
669
+ type: 'string',
670
+ demandOption: true
671
+ }).example('$0 schedule create my-brain "0 3 * * *"', 'Run my-brain daily at 3am').example('$0 schedule c my-brain "0 3 * * *"', 'Run my-brain daily at 3am (shorthand)').example('$0 schedule create data-sync "*/30 * * * *"', 'Run data-sync every 30 minutes').example('$0 schedule create weekly-report "0 9 * * 1"', 'Run weekly-report every Monday at 9am');
672
+ }, function(argv) {
673
+ var element = scheduleCommand.create(argv);
674
+ render(element);
675
+ }).command('runs', 'List scheduled run history\n', function(yargsRuns) {
676
+ return yargsRuns.option('schedule-id', {
677
+ describe: 'Filter runs by schedule ID',
678
+ type: 'string',
679
+ alias: 's'
680
+ }).option('limit', {
681
+ describe: 'Maximum number of runs to show',
682
+ type: 'number',
683
+ alias: 'n',
684
+ default: 20
685
+ }).option('status', {
686
+ describe: 'Filter by run status',
687
+ type: 'string',
688
+ choices: [
689
+ 'triggered',
690
+ 'failed',
691
+ 'complete'
692
+ ]
693
+ }).example('$0 schedule runs', 'List recent scheduled runs').example('$0 schedule runs --schedule-id abc123', 'List runs for a specific schedule').example('$0 schedule runs --status failed --limit 50', 'List last 50 failed scheduled runs');
694
+ }, function(argv) {
695
+ var element = scheduleCommand.runs(argv);
696
+ render(element);
697
+ });
698
+ return yargsSchedule;
699
+ });
700
+ // --- Secret Management Commands ---
701
+ cli = cli.command('secret', 'Manage secrets for your brains\n', function(yargsSecret) {
702
+ yargsSecret.command('list', 'List all secrets\n', {}, function() {
703
+ var element = secretCommand.list();
704
+ render(element);
705
+ }).command('create <name>', 'Create a new secret\n', function(yargsCreate) {
706
+ return yargsCreate.positional('name', {
707
+ describe: 'Name of the secret (e.g., ANTHROPIC_API_KEY)',
708
+ type: 'string',
709
+ demandOption: true
710
+ }).option('value', {
711
+ describe: 'Secret value (omit for secure input)',
712
+ type: 'string'
713
+ }).example('$0 secret create ANTHROPIC_API_KEY', 'Create a secret with secure input').example('$0 secret create DATABASE_URL --value "postgres://..."', 'Create a secret with direct value (not recommended)');
714
+ }, function(argv) {
715
+ var element = secretCommand.create(argv);
716
+ render(element);
717
+ }).command('delete <name>', 'Delete a secret\n', function(yargsDelete) {
718
+ return yargsDelete.positional('name', {
719
+ describe: 'Name of the secret to delete',
720
+ type: 'string',
721
+ demandOption: true
722
+ }).example('$0 secret delete ANTHROPIC_API_KEY', 'Delete a secret');
723
+ }, function(argv) {
724
+ var element = secretCommand.delete(argv);
725
+ render(element);
726
+ }).command('bulk [file]', 'Bulk upload secrets from a .env file\n', function(yargsBulk) {
727
+ return yargsBulk.positional('file', {
728
+ describe: 'Path to the .env file (defaults to .env in project root)',
729
+ type: 'string'
730
+ }).example('$0 secret bulk', 'Upload secrets from .env file in project root').example('$0 secret bulk .env.production', 'Upload secrets from a specific .env file');
731
+ }, function(argv) {
732
+ var element = secretCommand.bulk(argv);
733
+ render(element);
734
+ }).demandCommand(1, 'You need to specify a subcommand');
735
+ return yargsSecret;
736
+ });
737
+ cli = cli.epilogue('For more information, visit https://positronic.sh');
738
+ return cli;
739
+ }