satoridb 1.2.5 ā 1.2.6
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/cli.js +287 -278
- package/package.json +8 -3
package/cli.js
CHANGED
|
@@ -1,278 +1,287 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Satori Interactive CLI (Improved)
|
|
5
|
-
* - Command registry (easy to extend)
|
|
6
|
-
* - Robust arg parsing (quotes, escapes)
|
|
7
|
-
* - Fixed bugs (lecture args check, set_mindspace double call)
|
|
8
|
-
* - Better UX (history, tab completion, prompt context)
|
|
9
|
-
* - Centralized error handling
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// -------------------------------
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// -------------------------------
|
|
34
|
-
// Utils
|
|
35
|
-
// -------------------------------
|
|
36
|
-
function assertInstalled() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Satori Interactive CLI (Improved)
|
|
5
|
+
* - Command registry (easy to extend)
|
|
6
|
+
* - Robust arg parsing (quotes, escapes)
|
|
7
|
+
* - Fixed bugs (lecture args check, set_mindspace double call)
|
|
8
|
+
* - Better UX (history, tab completion, prompt context)
|
|
9
|
+
* - Centralized error handling
|
|
10
|
+
*/
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const satori_node_1 = require("satori-node");
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const os_1 = __importDefault(require("os"));
|
|
18
|
+
const fs_1 = __importDefault(require("fs"));
|
|
19
|
+
const child_process_1 = require("child_process");
|
|
20
|
+
const readline_1 = __importDefault(require("readline"));
|
|
21
|
+
// -------------------------------
|
|
22
|
+
// Globals / State
|
|
23
|
+
// -------------------------------
|
|
24
|
+
const binName = os_1.default.platform() === "win32" ? "satori.exe" : "satori";
|
|
25
|
+
const binPath = path_1.default.join(os_1.default.homedir(), ".satori", "bin", binName);
|
|
26
|
+
let satori = null;
|
|
27
|
+
let session = {
|
|
28
|
+
host: null,
|
|
29
|
+
user: null,
|
|
30
|
+
password: null,
|
|
31
|
+
mindspace: null,
|
|
32
|
+
};
|
|
33
|
+
// -------------------------------
|
|
34
|
+
// Utils
|
|
35
|
+
// -------------------------------
|
|
36
|
+
function assertInstalled() {
|
|
37
|
+
if (!fs_1.default.existsSync(binPath)) {
|
|
38
|
+
console.error("ā Satori binary not found. Reinstall the package.");
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function runBinary(args) {
|
|
43
|
+
assertInstalled();
|
|
44
|
+
const r = (0, child_process_1.spawnSync)(binPath, args, { stdio: "inherit" });
|
|
45
|
+
if (r.error)
|
|
46
|
+
throw r.error;
|
|
47
|
+
}
|
|
48
|
+
function parseArgs(line) {
|
|
49
|
+
const re = /"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|(\S+)/g;
|
|
50
|
+
const out = [];
|
|
51
|
+
let m;
|
|
52
|
+
while ((m = re.exec(line)))
|
|
53
|
+
out.push(m[1] ?? m[2] ?? m[3]);
|
|
54
|
+
return out.map(v => v.replace(/\\"/g, '"').replace(/\\'/g, "'"));
|
|
55
|
+
}
|
|
56
|
+
function parseData(v) {
|
|
57
|
+
if (typeof v !== "string")
|
|
58
|
+
return v;
|
|
59
|
+
const t = v.trim();
|
|
60
|
+
if (t === "true")
|
|
61
|
+
return true;
|
|
62
|
+
if (t === "false")
|
|
63
|
+
return false;
|
|
64
|
+
if (!isNaN(Number(t)) && t !== "")
|
|
65
|
+
return Number(t);
|
|
66
|
+
if (t.startsWith("{") || t.startsWith("[")) {
|
|
67
|
+
try {
|
|
68
|
+
return JSON.parse(t);
|
|
69
|
+
}
|
|
70
|
+
catch { }
|
|
71
|
+
}
|
|
72
|
+
return v;
|
|
73
|
+
}
|
|
74
|
+
function requireConn() {
|
|
75
|
+
if (!satori)
|
|
76
|
+
throw new Error("No active connection. Use: connect <host> [user] [password]");
|
|
77
|
+
}
|
|
78
|
+
function withCreds(p = {}) {
|
|
79
|
+
if (session.user)
|
|
80
|
+
p.user = session.user;
|
|
81
|
+
if (session.password)
|
|
82
|
+
p.password = session.password;
|
|
83
|
+
return p;
|
|
84
|
+
}
|
|
85
|
+
function promptLabel() {
|
|
86
|
+
return `satori${session.mindspace ? `:${session.mindspace}` : ""}> `;
|
|
87
|
+
}
|
|
88
|
+
// -------------------------------
|
|
89
|
+
// Commands Registry
|
|
90
|
+
// -------------------------------
|
|
91
|
+
const commands = {
|
|
92
|
+
help: {
|
|
93
|
+
desc: "Show help",
|
|
94
|
+
run() { showHelp(); }
|
|
95
|
+
},
|
|
96
|
+
exit: { run() { process.exit(0); } },
|
|
97
|
+
quit: { run() { process.exit(0); } },
|
|
98
|
+
clear: { run() { console.clear(); } },
|
|
99
|
+
connect: {
|
|
100
|
+
desc: "connect <host> [user] [password]",
|
|
101
|
+
async run([host, user = null, password = null]) {
|
|
102
|
+
if (!host)
|
|
103
|
+
throw new Error("Usage: connect <host> [user] [password]");
|
|
104
|
+
console.log(`š Connecting to ${host}...`);
|
|
105
|
+
if (user != null && password != null) {
|
|
106
|
+
satori = new satori_node_1.Satori({ host, username: user, password });
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
satori = new satori_node_1.Satori({ host: host, username: "", password: "" });
|
|
110
|
+
}
|
|
111
|
+
await satori.connect();
|
|
112
|
+
Object.assign(session, { host, user, password });
|
|
113
|
+
console.log("ā
Connected");
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
mindspace: {
|
|
117
|
+
desc: "mindspace select <id>",
|
|
118
|
+
run([sub, id]) {
|
|
119
|
+
if (sub !== "select" || !id)
|
|
120
|
+
throw new Error("Usage: mindspace select <id>");
|
|
121
|
+
session.mindspace = id;
|
|
122
|
+
console.log(`š§ Mindspace selected: ${id}`);
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
set: {
|
|
126
|
+
desc: "set <key> <data>",
|
|
127
|
+
async run([key, ...rest]) {
|
|
128
|
+
requireConn();
|
|
129
|
+
if (!key || !rest.length)
|
|
130
|
+
throw new Error("Usage: set <key> <data>");
|
|
131
|
+
const data = parseData(rest.join(" "));
|
|
132
|
+
await satori.set(withCreds({ key, data }));
|
|
133
|
+
console.log(`ā
Saved: ${key}`);
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
get: {
|
|
137
|
+
desc: "get <key>",
|
|
138
|
+
async run([key]) {
|
|
139
|
+
requireConn();
|
|
140
|
+
const r = await satori.get(withCreds(key ? { key } : {}));
|
|
141
|
+
console.log(JSON.stringify(r, null, 2));
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
put: {
|
|
145
|
+
desc: "put <key> <field> <value>",
|
|
146
|
+
async run([key, field, value]) {
|
|
147
|
+
requireConn();
|
|
148
|
+
if (!key || !field)
|
|
149
|
+
throw new Error("Usage: put <key> <field> <value>");
|
|
150
|
+
await satori.put(withCreds({ key, replace_field: field, replace_value: parseData(value) }));
|
|
151
|
+
console.log("ā
Updated");
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
delete: {
|
|
155
|
+
desc: "delete <key>",
|
|
156
|
+
async run([key]) {
|
|
157
|
+
requireConn();
|
|
158
|
+
if (!key)
|
|
159
|
+
throw new Error("Usage: delete <key>");
|
|
160
|
+
await satori.delete(withCreds({ key }));
|
|
161
|
+
console.log(`šļø Deleted: ${key}`);
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
ask: {
|
|
165
|
+
desc: "ask \"<question>\"",
|
|
166
|
+
async run([q, backend = null]) {
|
|
167
|
+
requireConn();
|
|
168
|
+
if (!q)
|
|
169
|
+
throw new Error("Usage: ask \"<question>\"");
|
|
170
|
+
const r = await satori.ask(withCreds({ question: q, backend }));
|
|
171
|
+
console.log(JSON.stringify(r, null, 2));
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
query: {
|
|
175
|
+
desc: "query \"<query>\"",
|
|
176
|
+
async run([q, backend = null]) {
|
|
177
|
+
requireConn();
|
|
178
|
+
if (!q)
|
|
179
|
+
throw new Error("Usage: query \"<query>\"");
|
|
180
|
+
const r = await satori.query(withCreds({ query: q, backend }));
|
|
181
|
+
console.log(JSON.stringify(r, null, 2));
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
chat: {
|
|
185
|
+
desc: "chat \"<message>\"",
|
|
186
|
+
async run([msg]) {
|
|
187
|
+
requireConn();
|
|
188
|
+
if (!session.mindspace)
|
|
189
|
+
throw new Error("Select a mindspace first");
|
|
190
|
+
const r = await satori.chatMindspace({ minspace_id: session.mindspace, message: msg });
|
|
191
|
+
console.log(r);
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
lecture: {
|
|
195
|
+
desc: "lecture \"<corpus>\"",
|
|
196
|
+
async run([corpus]) {
|
|
197
|
+
requireConn();
|
|
198
|
+
if (!session.mindspace)
|
|
199
|
+
throw new Error("Select a mindspace first");
|
|
200
|
+
const r = await satori.lectureMindspace({ mindspace_id: session.mindspace, corpus });
|
|
201
|
+
console.log(r.message);
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
set_mindspace: {
|
|
205
|
+
desc: "set_mindspace [mindspace_id]",
|
|
206
|
+
async run([mindspace_id = null]) {
|
|
207
|
+
requireConn();
|
|
208
|
+
if (!satori)
|
|
209
|
+
throw new Error("No active connection");
|
|
210
|
+
let payload = { config: {} };
|
|
211
|
+
if (mindspace_id)
|
|
212
|
+
payload.mindspace_id = mindspace_id;
|
|
213
|
+
else if (session.mindspace)
|
|
214
|
+
payload.mindspace_id = session.mindspace;
|
|
215
|
+
const res = await satori.setMindspace(payload);
|
|
216
|
+
if (payload.mindspace_id)
|
|
217
|
+
session.mindspace = payload.mindspace_id;
|
|
218
|
+
console.log(`š§ Mindspace configured: ${payload.mindspace_id ?? res.data}`);
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
// -------------------------------
|
|
223
|
+
// Help
|
|
224
|
+
// -------------------------------
|
|
225
|
+
function showHelp() {
|
|
226
|
+
console.log("\nš Commands:\n");
|
|
227
|
+
Object.entries(commands).forEach(([k, v]) => {
|
|
228
|
+
if ('desc' in v && v.desc)
|
|
229
|
+
console.log(` ${k.padEnd(12)} ${v.desc}`);
|
|
230
|
+
});
|
|
231
|
+
console.log("");
|
|
232
|
+
}
|
|
233
|
+
// -------------------------------
|
|
234
|
+
// Interactive Shell
|
|
235
|
+
// -------------------------------
|
|
236
|
+
async function startREPL() {
|
|
237
|
+
const rl = readline_1.default.createInterface({
|
|
238
|
+
input: process.stdin,
|
|
239
|
+
output: process.stdout,
|
|
240
|
+
historySize: 500,
|
|
241
|
+
completer(line) {
|
|
242
|
+
const hits = Object.keys(commands).filter(c => c.startsWith(line));
|
|
243
|
+
return [hits.length ? hits : Object.keys(commands), line];
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
const refreshPrompt = () => rl.setPrompt(promptLabel());
|
|
247
|
+
refreshPrompt();
|
|
248
|
+
rl.prompt();
|
|
249
|
+
rl.on("line", async (line) => {
|
|
250
|
+
const parts = parseArgs(line.trim());
|
|
251
|
+
if (!parts.length)
|
|
252
|
+
return rl.prompt();
|
|
253
|
+
const [cmd, ...args] = parts;
|
|
254
|
+
const entry = commands[cmd];
|
|
255
|
+
try {
|
|
256
|
+
if (!entry)
|
|
257
|
+
throw new Error("Unknown command. Type 'help'.");
|
|
258
|
+
if (satori == null) {
|
|
259
|
+
console.error("ā You are not connected");
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
await entry.run(args);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
catch (e) {
|
|
266
|
+
console.error("ā", e.message);
|
|
267
|
+
}
|
|
268
|
+
refreshPrompt();
|
|
269
|
+
rl.prompt();
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
// -------------------------------
|
|
273
|
+
// Entry
|
|
274
|
+
// -------------------------------
|
|
275
|
+
const argv = process.argv.slice(2);
|
|
276
|
+
if (argv[0] === "run") {
|
|
277
|
+
runBinary(argv.slice(1));
|
|
278
|
+
}
|
|
279
|
+
else if (argv[0] === "update") {
|
|
280
|
+
require("./postinstall");
|
|
281
|
+
}
|
|
282
|
+
else if (argv[0] === "verify") {
|
|
283
|
+
require("./verify-install");
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
startREPL();
|
|
287
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "satoridb",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.6",
|
|
4
4
|
"description": "Install satori",
|
|
5
5
|
"bin": {
|
|
6
6
|
"satoridb": "./cli.js"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
|
+
"build": "tsc cli.ts --outDir . --target es2020 --module commonjs --esModuleInterop",
|
|
9
10
|
"postinstall": "node postinstall.js",
|
|
10
11
|
"verify": "node verify-install.js"
|
|
11
12
|
},
|
|
@@ -13,12 +14,16 @@
|
|
|
13
14
|
"license": "ISC",
|
|
14
15
|
"dependencies": {
|
|
15
16
|
"adm-zip": "^0.5.16",
|
|
16
|
-
"satori-node": "^1.1.13"
|
|
17
|
+
"satori-node": "^1.1.13",
|
|
18
|
+
"typescript": "^5.9.3"
|
|
17
19
|
},
|
|
18
20
|
"files": [
|
|
19
21
|
"postinstall.js",
|
|
20
22
|
"add-to-path.ps1",
|
|
21
23
|
"add-to-path.sh",
|
|
22
24
|
"verify-install.js"
|
|
23
|
-
]
|
|
25
|
+
],
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^25.1.0"
|
|
28
|
+
}
|
|
24
29
|
}
|