@positronic/cli 0.0.71 → 0.0.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/cli.js +7 -0
- package/dist/src/commands/store.js +36 -0
- package/dist/src/components/store-explorer.js +699 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/commands/store.d.ts +5 -0
- package/dist/types/commands/store.d.ts.map +1 -0
- package/dist/types/components/store-explorer.d.ts +2 -0
- package/dist/types/components/store-explorer.d.ts.map +1 -0
- package/package.json +4 -4
package/dist/src/cli.js
CHANGED
|
@@ -162,6 +162,7 @@ import { SecretCommand } from './commands/secret.js';
|
|
|
162
162
|
import { PagesCommand } from './commands/pages.js';
|
|
163
163
|
import { UsersCommand } from './commands/users.js';
|
|
164
164
|
import { AuthCommand } from './commands/auth.js';
|
|
165
|
+
import { StoreCommand } from './commands/store.js';
|
|
165
166
|
import { readFileSync } from 'fs';
|
|
166
167
|
import { fileURLToPath } from 'url';
|
|
167
168
|
import { dirname, join } from 'path';
|
|
@@ -963,6 +964,12 @@ export function buildCli(options) {
|
|
|
963
964
|
}).demandCommand(1, 'You need to specify a users command (list, create, delete, keys)');
|
|
964
965
|
return yargsUsers;
|
|
965
966
|
});
|
|
967
|
+
// --- Store Explorer Command ---
|
|
968
|
+
var storeCommand = new StoreCommand();
|
|
969
|
+
cli = cli.command('store', 'Browse and manage brain store data\n', function() {}, function() {
|
|
970
|
+
var element = storeCommand.explore();
|
|
971
|
+
render(element);
|
|
972
|
+
});
|
|
966
973
|
// --- Auth Commands (Available in both local and global mode) ---
|
|
967
974
|
var authCommand = new AuthCommand(undefined, projectRootPath);
|
|
968
975
|
{
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
function _class_call_check(instance, Constructor) {
|
|
2
|
+
if (!(instance instanceof Constructor)) {
|
|
3
|
+
throw new TypeError("Cannot call a class as a function");
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
function _defineProperties(target, props) {
|
|
7
|
+
for(var i = 0; i < props.length; i++){
|
|
8
|
+
var descriptor = props[i];
|
|
9
|
+
descriptor.enumerable = descriptor.enumerable || false;
|
|
10
|
+
descriptor.configurable = true;
|
|
11
|
+
if ("value" in descriptor) descriptor.writable = true;
|
|
12
|
+
Object.defineProperty(target, descriptor.key, descriptor);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function _create_class(Constructor, protoProps, staticProps) {
|
|
16
|
+
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
17
|
+
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
18
|
+
return Constructor;
|
|
19
|
+
}
|
|
20
|
+
import React from 'react';
|
|
21
|
+
import { StoreExplorer } from '../components/store-explorer.js';
|
|
22
|
+
export var StoreCommand = /*#__PURE__*/ function() {
|
|
23
|
+
"use strict";
|
|
24
|
+
function StoreCommand() {
|
|
25
|
+
_class_call_check(this, StoreCommand);
|
|
26
|
+
}
|
|
27
|
+
_create_class(StoreCommand, [
|
|
28
|
+
{
|
|
29
|
+
key: "explore",
|
|
30
|
+
value: function explore() {
|
|
31
|
+
return React.createElement(StoreExplorer);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
]);
|
|
35
|
+
return StoreCommand;
|
|
36
|
+
}();
|
|
@@ -0,0 +1,699 @@
|
|
|
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 asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
10
|
+
try {
|
|
11
|
+
var info = gen[key](arg);
|
|
12
|
+
var value = info.value;
|
|
13
|
+
} catch (error) {
|
|
14
|
+
reject(error);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (info.done) {
|
|
18
|
+
resolve(value);
|
|
19
|
+
} else {
|
|
20
|
+
Promise.resolve(value).then(_next, _throw);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function _async_to_generator(fn) {
|
|
24
|
+
return function() {
|
|
25
|
+
var self = this, args = arguments;
|
|
26
|
+
return new Promise(function(resolve, reject) {
|
|
27
|
+
var gen = fn.apply(self, args);
|
|
28
|
+
function _next(value) {
|
|
29
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
30
|
+
}
|
|
31
|
+
function _throw(err) {
|
|
32
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
33
|
+
}
|
|
34
|
+
_next(undefined);
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function _iterable_to_array_limit(arr, i) {
|
|
39
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
40
|
+
if (_i == null) return;
|
|
41
|
+
var _arr = [];
|
|
42
|
+
var _n = true;
|
|
43
|
+
var _d = false;
|
|
44
|
+
var _s, _e;
|
|
45
|
+
try {
|
|
46
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
47
|
+
_arr.push(_s.value);
|
|
48
|
+
if (i && _arr.length === i) break;
|
|
49
|
+
}
|
|
50
|
+
} catch (err) {
|
|
51
|
+
_d = true;
|
|
52
|
+
_e = err;
|
|
53
|
+
} finally{
|
|
54
|
+
try {
|
|
55
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
56
|
+
} finally{
|
|
57
|
+
if (_d) throw _e;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return _arr;
|
|
61
|
+
}
|
|
62
|
+
function _non_iterable_rest() {
|
|
63
|
+
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
|
+
}
|
|
65
|
+
function _sliced_to_array(arr, i) {
|
|
66
|
+
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
67
|
+
}
|
|
68
|
+
function _type_of(obj) {
|
|
69
|
+
"@swc/helpers - typeof";
|
|
70
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
71
|
+
}
|
|
72
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
73
|
+
if (!o) return;
|
|
74
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
75
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
76
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
77
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
78
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
79
|
+
}
|
|
80
|
+
function _ts_generator(thisArg, body) {
|
|
81
|
+
var f, y, t, _ = {
|
|
82
|
+
label: 0,
|
|
83
|
+
sent: function() {
|
|
84
|
+
if (t[0] & 1) throw t[1];
|
|
85
|
+
return t[1];
|
|
86
|
+
},
|
|
87
|
+
trys: [],
|
|
88
|
+
ops: []
|
|
89
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
90
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
91
|
+
return this;
|
|
92
|
+
}), g;
|
|
93
|
+
function verb(n) {
|
|
94
|
+
return function(v) {
|
|
95
|
+
return step([
|
|
96
|
+
n,
|
|
97
|
+
v
|
|
98
|
+
]);
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function step(op) {
|
|
102
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
103
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
104
|
+
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;
|
|
105
|
+
if (y = 0, t) op = [
|
|
106
|
+
op[0] & 2,
|
|
107
|
+
t.value
|
|
108
|
+
];
|
|
109
|
+
switch(op[0]){
|
|
110
|
+
case 0:
|
|
111
|
+
case 1:
|
|
112
|
+
t = op;
|
|
113
|
+
break;
|
|
114
|
+
case 4:
|
|
115
|
+
_.label++;
|
|
116
|
+
return {
|
|
117
|
+
value: op[1],
|
|
118
|
+
done: false
|
|
119
|
+
};
|
|
120
|
+
case 5:
|
|
121
|
+
_.label++;
|
|
122
|
+
y = op[1];
|
|
123
|
+
op = [
|
|
124
|
+
0
|
|
125
|
+
];
|
|
126
|
+
continue;
|
|
127
|
+
case 7:
|
|
128
|
+
op = _.ops.pop();
|
|
129
|
+
_.trys.pop();
|
|
130
|
+
continue;
|
|
131
|
+
default:
|
|
132
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
133
|
+
_ = 0;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
137
|
+
_.label = op[1];
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
141
|
+
_.label = t[1];
|
|
142
|
+
t = op;
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
if (t && _.label < t[2]) {
|
|
146
|
+
_.label = t[2];
|
|
147
|
+
_.ops.push(op);
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
if (t[2]) _.ops.pop();
|
|
151
|
+
_.trys.pop();
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
op = body.call(thisArg, _);
|
|
155
|
+
} catch (e) {
|
|
156
|
+
op = [
|
|
157
|
+
6,
|
|
158
|
+
e
|
|
159
|
+
];
|
|
160
|
+
y = 0;
|
|
161
|
+
} finally{
|
|
162
|
+
f = t = 0;
|
|
163
|
+
}
|
|
164
|
+
if (op[0] & 5) throw op[1];
|
|
165
|
+
return {
|
|
166
|
+
value: op[0] ? op[1] : void 0,
|
|
167
|
+
done: true
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
|
172
|
+
import { Text, Box, useStdout, useInput, useApp } from 'ink';
|
|
173
|
+
import { apiClient } from '../commands/helpers.js';
|
|
174
|
+
import { ErrorComponent } from './error.js';
|
|
175
|
+
import { StateView } from './state-view.js';
|
|
176
|
+
export var StoreExplorer = function() {
|
|
177
|
+
var write = useStdout().write;
|
|
178
|
+
var exit = useApp().exit;
|
|
179
|
+
// Navigation state
|
|
180
|
+
var _useState = _sliced_to_array(useState('brains'), 2), mode = _useState[0], setMode = _useState[1];
|
|
181
|
+
var _useState1 = _sliced_to_array(useState(0), 2), selectedIndex = _useState1[0], setSelectedIndex = _useState1[1];
|
|
182
|
+
// Data state
|
|
183
|
+
var _useState2 = _sliced_to_array(useState([]), 2), brains = _useState2[0], setBrains = _useState2[1];
|
|
184
|
+
var _useState3 = _sliced_to_array(useState(null), 2), selectedBrain = _useState3[0], setSelectedBrain = _useState3[1];
|
|
185
|
+
var _useState4 = _sliced_to_array(useState([]), 2), keys = _useState4[0], setKeys = _useState4[1];
|
|
186
|
+
var _useState5 = _sliced_to_array(useState(null), 2), selectedKey = _useState5[0], setSelectedKey = _useState5[1];
|
|
187
|
+
var _useState6 = _sliced_to_array(useState(null), 2), value = _useState6[0], setValue = _useState6[1];
|
|
188
|
+
// Loading/error state
|
|
189
|
+
var _useState7 = _sliced_to_array(useState(true), 2), loading = _useState7[0], setLoading = _useState7[1];
|
|
190
|
+
var _useState8 = _sliced_to_array(useState(null), 2), error = _useState8[0], setError = _useState8[1];
|
|
191
|
+
// Delete confirmation state
|
|
192
|
+
var _useState9 = _sliced_to_array(useState(false), 2), confirmingDelete = _useState9[0], setConfirmingDelete = _useState9[1];
|
|
193
|
+
var _useState10 = _sliced_to_array(useState(false), 2), confirmingClear = _useState10[0], setConfirmingClear = _useState10[1];
|
|
194
|
+
var _useState11 = _sliced_to_array(useState(null), 2), deleteMessage = _useState11[0], setDeleteMessage = _useState11[1];
|
|
195
|
+
// Scroll state for value view
|
|
196
|
+
var _useState12 = _sliced_to_array(useState(0), 2), scrollOffset = _useState12[0], setScrollOffset = _useState12[1];
|
|
197
|
+
// Refetch trigger
|
|
198
|
+
var _useState13 = _sliced_to_array(useState(0), 2), fetchVersion = _useState13[0], setFetchVersion = _useState13[1];
|
|
199
|
+
// Use a ref to hold the latest input handler so useInput always
|
|
200
|
+
// calls through to current state, avoiding stale closure issues
|
|
201
|
+
// caused by useEffect re-registration timing in ink's useInput.
|
|
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
|
+
]);
|
|
215
|
+
// Fetch brains list
|
|
216
|
+
useEffect(function() {
|
|
217
|
+
if (mode !== 'brains') return;
|
|
218
|
+
var fetchBrains = function() {
|
|
219
|
+
return _async_to_generator(function() {
|
|
220
|
+
var response, data, err;
|
|
221
|
+
return _ts_generator(this, function(_state) {
|
|
222
|
+
switch(_state.label){
|
|
223
|
+
case 0:
|
|
224
|
+
setLoading(true);
|
|
225
|
+
setError(null);
|
|
226
|
+
_state.label = 1;
|
|
227
|
+
case 1:
|
|
228
|
+
_state.trys.push([
|
|
229
|
+
1,
|
|
230
|
+
4,
|
|
231
|
+
5,
|
|
232
|
+
6
|
|
233
|
+
]);
|
|
234
|
+
return [
|
|
235
|
+
4,
|
|
236
|
+
apiClient.fetch('/store')
|
|
237
|
+
];
|
|
238
|
+
case 2:
|
|
239
|
+
response = _state.sent();
|
|
240
|
+
if (!response.ok) {
|
|
241
|
+
setError({
|
|
242
|
+
title: 'Server Error',
|
|
243
|
+
message: "Failed to load store data: ".concat(response.status)
|
|
244
|
+
});
|
|
245
|
+
return [
|
|
246
|
+
2
|
|
247
|
+
];
|
|
248
|
+
}
|
|
249
|
+
return [
|
|
250
|
+
4,
|
|
251
|
+
response.json()
|
|
252
|
+
];
|
|
253
|
+
case 3:
|
|
254
|
+
data = _state.sent();
|
|
255
|
+
setBrains(data.brains);
|
|
256
|
+
return [
|
|
257
|
+
3,
|
|
258
|
+
6
|
|
259
|
+
];
|
|
260
|
+
case 4:
|
|
261
|
+
err = _state.sent();
|
|
262
|
+
setError({
|
|
263
|
+
title: 'Connection Error',
|
|
264
|
+
message: 'Error connecting to the server.',
|
|
265
|
+
details: err.message
|
|
266
|
+
});
|
|
267
|
+
return [
|
|
268
|
+
3,
|
|
269
|
+
6
|
|
270
|
+
];
|
|
271
|
+
case 5:
|
|
272
|
+
setLoading(false);
|
|
273
|
+
return [
|
|
274
|
+
7
|
|
275
|
+
];
|
|
276
|
+
case 6:
|
|
277
|
+
return [
|
|
278
|
+
2
|
|
279
|
+
];
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
})();
|
|
283
|
+
};
|
|
284
|
+
fetchBrains();
|
|
285
|
+
}, [
|
|
286
|
+
mode,
|
|
287
|
+
fetchVersion
|
|
288
|
+
]);
|
|
289
|
+
// Fetch keys when a brain is selected
|
|
290
|
+
useEffect(function() {
|
|
291
|
+
if (mode !== 'keys' || !selectedBrain) return;
|
|
292
|
+
var fetchKeys = function() {
|
|
293
|
+
return _async_to_generator(function() {
|
|
294
|
+
var response, data, err;
|
|
295
|
+
return _ts_generator(this, function(_state) {
|
|
296
|
+
switch(_state.label){
|
|
297
|
+
case 0:
|
|
298
|
+
// Don't show loading spinner during background refetch after delete/clear
|
|
299
|
+
if (!deleteMessage) {
|
|
300
|
+
setLoading(true);
|
|
301
|
+
}
|
|
302
|
+
setError(null);
|
|
303
|
+
_state.label = 1;
|
|
304
|
+
case 1:
|
|
305
|
+
_state.trys.push([
|
|
306
|
+
1,
|
|
307
|
+
4,
|
|
308
|
+
5,
|
|
309
|
+
6
|
|
310
|
+
]);
|
|
311
|
+
return [
|
|
312
|
+
4,
|
|
313
|
+
apiClient.fetch("/store/".concat(encodeURIComponent(selectedBrain)))
|
|
314
|
+
];
|
|
315
|
+
case 2:
|
|
316
|
+
response = _state.sent();
|
|
317
|
+
if (!response.ok) {
|
|
318
|
+
setError({
|
|
319
|
+
title: 'Server Error',
|
|
320
|
+
message: "Failed to load keys: ".concat(response.status)
|
|
321
|
+
});
|
|
322
|
+
return [
|
|
323
|
+
2
|
|
324
|
+
];
|
|
325
|
+
}
|
|
326
|
+
return [
|
|
327
|
+
4,
|
|
328
|
+
response.json()
|
|
329
|
+
];
|
|
330
|
+
case 3:
|
|
331
|
+
data = _state.sent();
|
|
332
|
+
setKeys(data.keys);
|
|
333
|
+
return [
|
|
334
|
+
3,
|
|
335
|
+
6
|
|
336
|
+
];
|
|
337
|
+
case 4:
|
|
338
|
+
err = _state.sent();
|
|
339
|
+
setError({
|
|
340
|
+
title: 'Connection Error',
|
|
341
|
+
message: 'Error connecting to the server.',
|
|
342
|
+
details: err.message
|
|
343
|
+
});
|
|
344
|
+
return [
|
|
345
|
+
3,
|
|
346
|
+
6
|
|
347
|
+
];
|
|
348
|
+
case 5:
|
|
349
|
+
setLoading(false);
|
|
350
|
+
return [
|
|
351
|
+
7
|
|
352
|
+
];
|
|
353
|
+
case 6:
|
|
354
|
+
return [
|
|
355
|
+
2
|
|
356
|
+
];
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
})();
|
|
360
|
+
};
|
|
361
|
+
fetchKeys();
|
|
362
|
+
}, [
|
|
363
|
+
mode,
|
|
364
|
+
selectedBrain,
|
|
365
|
+
fetchVersion
|
|
366
|
+
]);
|
|
367
|
+
// Fetch value when a key is selected
|
|
368
|
+
useEffect(function() {
|
|
369
|
+
if (mode !== 'value' || !selectedBrain || !selectedKey) return;
|
|
370
|
+
var fetchValue = function() {
|
|
371
|
+
return _async_to_generator(function() {
|
|
372
|
+
var scopePath, response, data, err;
|
|
373
|
+
return _ts_generator(this, function(_state) {
|
|
374
|
+
switch(_state.label){
|
|
375
|
+
case 0:
|
|
376
|
+
setLoading(true);
|
|
377
|
+
setError(null);
|
|
378
|
+
_state.label = 1;
|
|
379
|
+
case 1:
|
|
380
|
+
_state.trys.push([
|
|
381
|
+
1,
|
|
382
|
+
4,
|
|
383
|
+
5,
|
|
384
|
+
6
|
|
385
|
+
]);
|
|
386
|
+
scopePath = selectedKey.scope === 'shared' ? 'shared' : 'user';
|
|
387
|
+
return [
|
|
388
|
+
4,
|
|
389
|
+
apiClient.fetch("/store/".concat(encodeURIComponent(selectedBrain), "/").concat(scopePath, "/").concat(encodeURIComponent(selectedKey.key)))
|
|
390
|
+
];
|
|
391
|
+
case 2:
|
|
392
|
+
response = _state.sent();
|
|
393
|
+
if (!response.ok) {
|
|
394
|
+
setError({
|
|
395
|
+
title: 'Server Error',
|
|
396
|
+
message: "Failed to load value: ".concat(response.status)
|
|
397
|
+
});
|
|
398
|
+
return [
|
|
399
|
+
2
|
|
400
|
+
];
|
|
401
|
+
}
|
|
402
|
+
return [
|
|
403
|
+
4,
|
|
404
|
+
response.json()
|
|
405
|
+
];
|
|
406
|
+
case 3:
|
|
407
|
+
data = _state.sent();
|
|
408
|
+
setValue(data);
|
|
409
|
+
setScrollOffset(0);
|
|
410
|
+
return [
|
|
411
|
+
3,
|
|
412
|
+
6
|
|
413
|
+
];
|
|
414
|
+
case 4:
|
|
415
|
+
err = _state.sent();
|
|
416
|
+
setError({
|
|
417
|
+
title: 'Connection Error',
|
|
418
|
+
message: 'Error connecting to the server.',
|
|
419
|
+
details: err.message
|
|
420
|
+
});
|
|
421
|
+
return [
|
|
422
|
+
3,
|
|
423
|
+
6
|
|
424
|
+
];
|
|
425
|
+
case 5:
|
|
426
|
+
setLoading(false);
|
|
427
|
+
return [
|
|
428
|
+
7
|
|
429
|
+
];
|
|
430
|
+
case 6:
|
|
431
|
+
return [
|
|
432
|
+
2
|
|
433
|
+
];
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
})();
|
|
437
|
+
};
|
|
438
|
+
fetchValue();
|
|
439
|
+
}, [
|
|
440
|
+
mode,
|
|
441
|
+
selectedBrain,
|
|
442
|
+
selectedKey,
|
|
443
|
+
fetchVersion
|
|
444
|
+
]);
|
|
445
|
+
// Update the ref with the latest handler on every render
|
|
446
|
+
inputHandlerRef.current = function(input, key) {
|
|
447
|
+
// Clear delete message on any input
|
|
448
|
+
if (deleteMessage) {
|
|
449
|
+
setDeleteMessage(null);
|
|
450
|
+
}
|
|
451
|
+
if (mode === 'brains') {
|
|
452
|
+
if ((key.upArrow || input === 'k') && brains.length > 0) {
|
|
453
|
+
setSelectedIndex(function(prev) {
|
|
454
|
+
return (prev - 1 + brains.length) % brains.length;
|
|
455
|
+
});
|
|
456
|
+
} else if ((key.downArrow || input === 'j') && brains.length > 0) {
|
|
457
|
+
setSelectedIndex(function(prev) {
|
|
458
|
+
return (prev + 1) % brains.length;
|
|
459
|
+
});
|
|
460
|
+
} else if (key.return && brains.length > 0) {
|
|
461
|
+
setSelectedBrain(brains[selectedIndex]);
|
|
462
|
+
setSelectedIndex(0);
|
|
463
|
+
setMode('keys');
|
|
464
|
+
} else if (input === 'q' || key.escape) {
|
|
465
|
+
exit();
|
|
466
|
+
}
|
|
467
|
+
} else if (mode === 'keys') {
|
|
468
|
+
// Handle delete confirmation
|
|
469
|
+
if (confirmingDelete) {
|
|
470
|
+
if (input === 'y') {
|
|
471
|
+
var keyToDelete = keys[selectedIndex];
|
|
472
|
+
if (keyToDelete && selectedBrain) {
|
|
473
|
+
setConfirmingDelete(false);
|
|
474
|
+
var scopePath = keyToDelete.scope === 'shared' ? 'shared' : 'user';
|
|
475
|
+
apiClient.fetch("/store/".concat(encodeURIComponent(selectedBrain), "/").concat(scopePath, "/").concat(encodeURIComponent(keyToDelete.key)), {
|
|
476
|
+
method: 'DELETE'
|
|
477
|
+
}).then(function() {
|
|
478
|
+
setDeleteMessage("Deleted: ".concat(keyToDelete.key));
|
|
479
|
+
setFetchVersion(function(v) {
|
|
480
|
+
return v + 1;
|
|
481
|
+
});
|
|
482
|
+
if (selectedIndex >= keys.length - 1) {
|
|
483
|
+
setSelectedIndex(Math.max(0, keys.length - 2));
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
} else if (input === 'n' || key.escape) {
|
|
488
|
+
setConfirmingDelete(false);
|
|
489
|
+
}
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
// Handle clear confirmation
|
|
493
|
+
if (confirmingClear) {
|
|
494
|
+
if (input === 'y') {
|
|
495
|
+
if (selectedBrain) {
|
|
496
|
+
setConfirmingClear(false);
|
|
497
|
+
apiClient.fetch("/store/".concat(encodeURIComponent(selectedBrain)), {
|
|
498
|
+
method: 'DELETE'
|
|
499
|
+
}).then(function(res) {
|
|
500
|
+
return _async_to_generator(function() {
|
|
501
|
+
var data;
|
|
502
|
+
return _ts_generator(this, function(_state) {
|
|
503
|
+
switch(_state.label){
|
|
504
|
+
case 0:
|
|
505
|
+
return [
|
|
506
|
+
4,
|
|
507
|
+
res.json()
|
|
508
|
+
];
|
|
509
|
+
case 1:
|
|
510
|
+
data = _state.sent();
|
|
511
|
+
setDeleteMessage("Cleared ".concat(data.deleted, " keys"));
|
|
512
|
+
setFetchVersion(function(v) {
|
|
513
|
+
return v + 1;
|
|
514
|
+
});
|
|
515
|
+
setSelectedIndex(0);
|
|
516
|
+
return [
|
|
517
|
+
2
|
|
518
|
+
];
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
})();
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
} else if (input === 'n' || key.escape) {
|
|
525
|
+
setConfirmingClear(false);
|
|
526
|
+
}
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
// Normal key list navigation
|
|
530
|
+
if ((key.upArrow || input === 'k') && keys.length > 0) {
|
|
531
|
+
setSelectedIndex(function(prev) {
|
|
532
|
+
return (prev - 1 + keys.length) % keys.length;
|
|
533
|
+
});
|
|
534
|
+
} else if ((key.downArrow || input === 'j') && keys.length > 0) {
|
|
535
|
+
setSelectedIndex(function(prev) {
|
|
536
|
+
return (prev + 1) % keys.length;
|
|
537
|
+
});
|
|
538
|
+
} else if (key.return && keys.length > 0) {
|
|
539
|
+
setSelectedKey(keys[selectedIndex]);
|
|
540
|
+
setMode('value');
|
|
541
|
+
} else if (input === 'd' && keys.length > 0) {
|
|
542
|
+
setConfirmingDelete(true);
|
|
543
|
+
} else if (input === 'c' && keys.length > 0) {
|
|
544
|
+
setConfirmingClear(true);
|
|
545
|
+
} else if (input === 'b' || key.escape) {
|
|
546
|
+
setSelectedBrain(null);
|
|
547
|
+
setSelectedIndex(0);
|
|
548
|
+
setMode('brains');
|
|
549
|
+
}
|
|
550
|
+
} else if (mode === 'value') {
|
|
551
|
+
// Value view - StateView handles j/k/space scrolling via isActive
|
|
552
|
+
if (input === 'b' || key.escape) {
|
|
553
|
+
setSelectedKey(null);
|
|
554
|
+
setValue(null);
|
|
555
|
+
setMode('keys');
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
// Stable callback that delegates to the ref - never changes identity,
|
|
560
|
+
// so ink's useInput useEffect won't need to re-register the listener.
|
|
561
|
+
var stableInputHandler = useCallback(function(input, key) {
|
|
562
|
+
inputHandlerRef.current(input, key);
|
|
563
|
+
}, []);
|
|
564
|
+
// Keyboard handling - uses stable callback to avoid stale closure issues
|
|
565
|
+
useInput(stableInputHandler, {
|
|
566
|
+
isActive: mode !== 'value'
|
|
567
|
+
});
|
|
568
|
+
// Adjust selectedIndex if list shrinks
|
|
569
|
+
useEffect(function() {
|
|
570
|
+
var listLength = mode === 'brains' ? brains.length : mode === 'keys' ? keys.length : 0;
|
|
571
|
+
if (listLength > 0 && selectedIndex >= listLength) {
|
|
572
|
+
setSelectedIndex(listLength - 1);
|
|
573
|
+
}
|
|
574
|
+
}, [
|
|
575
|
+
brains.length,
|
|
576
|
+
keys.length,
|
|
577
|
+
selectedIndex,
|
|
578
|
+
mode
|
|
579
|
+
]);
|
|
580
|
+
// Error state
|
|
581
|
+
if (error) {
|
|
582
|
+
return /*#__PURE__*/ React.createElement(ErrorComponent, {
|
|
583
|
+
error: error
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
// Loading state - skip when there's a delete message so it stays visible
|
|
587
|
+
if (loading && !deleteMessage) {
|
|
588
|
+
return /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, null, "Loading..."));
|
|
589
|
+
}
|
|
590
|
+
// Value view
|
|
591
|
+
if (mode === 'value' && value) {
|
|
592
|
+
var stateObj = _type_of(value.value) === 'object' && value.value !== null ? value.value : {
|
|
593
|
+
value: value.value
|
|
594
|
+
};
|
|
595
|
+
var title = "".concat(selectedBrain, " / ").concat(value.key, " (").concat(value.scope, ")");
|
|
596
|
+
return /*#__PURE__*/ React.createElement(Box, {
|
|
597
|
+
flexDirection: "column"
|
|
598
|
+
}, /*#__PURE__*/ React.createElement(StateView, {
|
|
599
|
+
state: stateObj,
|
|
600
|
+
title: title,
|
|
601
|
+
scrollOffset: scrollOffset,
|
|
602
|
+
onScrollChange: setScrollOffset,
|
|
603
|
+
isActive: true
|
|
604
|
+
}), /*#__PURE__*/ React.createElement(Box, {
|
|
605
|
+
marginTop: 1
|
|
606
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
607
|
+
dimColor: true
|
|
608
|
+
}, "j/k scroll | space page | b back")));
|
|
609
|
+
}
|
|
610
|
+
// Keys view
|
|
611
|
+
if (mode === 'keys' && selectedBrain) {
|
|
612
|
+
if (keys.length === 0) {
|
|
613
|
+
return /*#__PURE__*/ React.createElement(Box, {
|
|
614
|
+
flexDirection: "column"
|
|
615
|
+
}, /*#__PURE__*/ React.createElement(Box, {
|
|
616
|
+
marginBottom: 1
|
|
617
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
618
|
+
bold: true,
|
|
619
|
+
color: "cyan"
|
|
620
|
+
}, "Store: ", selectedBrain)), deleteMessage && /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
|
|
621
|
+
color: "green"
|
|
622
|
+
}, deleteMessage)), /*#__PURE__*/ React.createElement(Text, {
|
|
623
|
+
dimColor: true
|
|
624
|
+
}, "No keys found"), /*#__PURE__*/ React.createElement(Box, {
|
|
625
|
+
marginTop: 1
|
|
626
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
627
|
+
dimColor: true
|
|
628
|
+
}, "b back | q quit")));
|
|
629
|
+
}
|
|
630
|
+
var footer;
|
|
631
|
+
if (confirmingDelete) {
|
|
632
|
+
var keyEntry = keys[selectedIndex];
|
|
633
|
+
footer = 'Delete "'.concat(keyEntry === null || keyEntry === void 0 ? void 0 : keyEntry.key, '"? (y/n)');
|
|
634
|
+
} else if (confirmingClear) {
|
|
635
|
+
footer = 'Clear all keys for "'.concat(selectedBrain, '"? (y/n)');
|
|
636
|
+
} else {
|
|
637
|
+
footer = 'j/k select | Enter view | d delete | c clear all | b back';
|
|
638
|
+
}
|
|
639
|
+
return /*#__PURE__*/ React.createElement(Box, {
|
|
640
|
+
flexDirection: "column"
|
|
641
|
+
}, /*#__PURE__*/ React.createElement(Box, {
|
|
642
|
+
marginBottom: 1
|
|
643
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
644
|
+
bold: true,
|
|
645
|
+
color: "cyan"
|
|
646
|
+
}, "Store: ", selectedBrain, " (", keys.length, " keys)")), keys.map(function(entry, i) {
|
|
647
|
+
return /*#__PURE__*/ React.createElement(Box, {
|
|
648
|
+
key: "".concat(entry.scope, "-").concat(entry.key, "-").concat(entry.userId || '')
|
|
649
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
650
|
+
color: i === selectedIndex ? 'cyan' : undefined
|
|
651
|
+
}, i === selectedIndex ? '> ' : ' ', entry.key, /*#__PURE__*/ React.createElement(Text, {
|
|
652
|
+
dimColor: true
|
|
653
|
+
}, ' ', "[", entry.scope, entry.userId ? ":".concat(entry.userId) : '', "] ", entry.size, "B")));
|
|
654
|
+
}), deleteMessage && /*#__PURE__*/ React.createElement(Box, {
|
|
655
|
+
marginTop: 1
|
|
656
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
657
|
+
color: "green"
|
|
658
|
+
}, deleteMessage)), /*#__PURE__*/ React.createElement(Box, {
|
|
659
|
+
marginTop: 1
|
|
660
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
661
|
+
dimColor: true
|
|
662
|
+
}, footer)));
|
|
663
|
+
}
|
|
664
|
+
// Brains view (default)
|
|
665
|
+
if (brains.length === 0) {
|
|
666
|
+
return /*#__PURE__*/ React.createElement(Box, {
|
|
667
|
+
flexDirection: "column"
|
|
668
|
+
}, /*#__PURE__*/ React.createElement(Box, {
|
|
669
|
+
marginBottom: 1
|
|
670
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
671
|
+
bold: true,
|
|
672
|
+
color: "cyan"
|
|
673
|
+
}, "Store Explorer")), /*#__PURE__*/ React.createElement(Text, {
|
|
674
|
+
dimColor: true
|
|
675
|
+
}, "No brains with store data found"), /*#__PURE__*/ React.createElement(Box, {
|
|
676
|
+
marginTop: 1
|
|
677
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
678
|
+
dimColor: true
|
|
679
|
+
}, "Use .withStore() in your brain definition to persist data")));
|
|
680
|
+
}
|
|
681
|
+
return /*#__PURE__*/ React.createElement(Box, {
|
|
682
|
+
flexDirection: "column"
|
|
683
|
+
}, /*#__PURE__*/ React.createElement(Box, {
|
|
684
|
+
marginBottom: 1
|
|
685
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
686
|
+
bold: true,
|
|
687
|
+
color: "cyan"
|
|
688
|
+
}, "Store Explorer (", brains.length, " brains)")), brains.map(function(brain, i) {
|
|
689
|
+
return /*#__PURE__*/ React.createElement(Box, {
|
|
690
|
+
key: brain
|
|
691
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
692
|
+
color: i === selectedIndex ? 'cyan' : undefined
|
|
693
|
+
}, i === selectedIndex ? '> ' : ' ', brain));
|
|
694
|
+
}), /*#__PURE__*/ React.createElement(Box, {
|
|
695
|
+
marginTop: 1
|
|
696
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
697
|
+
dimColor: true
|
|
698
|
+
}, "j/k select | Enter explore | q quit")));
|
|
699
|
+
};
|
package/dist/types/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAW1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAK5D,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,KAAK,GAAG,CAAC;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAoBD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,UAAU,4BA67C3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/commands/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,qBAAa,YAAY;IACvB,OAAO,IAAI,KAAK,CAAC,YAAY;CAG9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-explorer.d.ts","sourceRoot":"","sources":["../../../src/components/store-explorer.tsx"],"names":[],"mappings":"AA0CA,eAAO,MAAM,aAAa,+CA8ZzB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@positronic/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.73",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"clean": "rm -rf tsconfig.tsbuildinfo dist node_modules"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@positronic/core": "^0.0.
|
|
27
|
-
"@positronic/spec": "^0.0.
|
|
28
|
-
"@positronic/template-new-project": "^0.0.
|
|
26
|
+
"@positronic/core": "^0.0.73",
|
|
27
|
+
"@positronic/spec": "^0.0.73",
|
|
28
|
+
"@positronic/template-new-project": "^0.0.73",
|
|
29
29
|
"caz": "^2.0.0",
|
|
30
30
|
"chokidar": "^3.6.0",
|
|
31
31
|
"dotenv": "^16.4.7",
|