klio 1.4.9 → 1.5.1
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/.dockerignore +9 -0
- package/.nvmrc +1 -0
- package/Dockerfile +18 -0
- package/README.md +22 -0
- package/compose.yaml +6 -0
- package/package.json +8 -3
- package/src/astrology/astrologyConstants.js +7 -0
- package/src/astrology/astrologyService.js +327 -302
- package/src/astrology/astrologyServiceWeb.js +369 -0
- package/src/astrology/swephWasmLoader.js +106 -0
- package/src/astrology/swissephAdapter.js +279 -0
- package/src/cli/cli.js +148 -152
- package/src/cli/cliService.js +1197 -0
- package/src/cli/cliServiceWeb.js +406 -0
- package/src/config/configService.js +59 -35
- package/src/gui/public/index.html +839 -298
- package/src/gui/public/sweph/astro.data +0 -0
- package/src/gui/public/sweph/astro.js +3934 -0
- package/src/gui/public/sweph/astro.wasm +0 -0
- package/src/gui/public/tailwind.css +3 -0
- package/src/gui/public/tailwind.generated.css +1 -0
- package/src/gui/public/webcontainerService.js +435 -0
- package/src/gui/routes/api.js +64 -101
- package/src/gui/server.js +80 -31
- package/src/gui/webcontainerSetup.js +244 -0
- package/src/health/fileAnalysis.js +2 -2
- package/commands.db +0 -0
- package/src/gui/commandLogger.js +0 -67
- package/src/gui/database.js +0 -135
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
// WebContainer-compatible CLI Service
|
|
2
|
+
// This is a simplified version of the CLI service that works in WebContainers
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { planets, signs } = require('../astrology/astrologyConstants');
|
|
7
|
+
const astrologyService = require('../astrology/astrologyServiceWeb');
|
|
8
|
+
|
|
9
|
+
const SUPPORTED_OPTIONS = new Set(['c', 'rx', 'el', 's', 'status', 'people', 'setup', 'help', 'h']);
|
|
10
|
+
const CONFIG_PATH = '/home/astrocli/config.json';
|
|
11
|
+
|
|
12
|
+
function splitCommandArgs(commandString) {
|
|
13
|
+
const args = [];
|
|
14
|
+
let current = '';
|
|
15
|
+
let quoteChar = null;
|
|
16
|
+
let escaped = false;
|
|
17
|
+
|
|
18
|
+
for (let i = 0; i < commandString.length; i++) {
|
|
19
|
+
const char = commandString[i];
|
|
20
|
+
|
|
21
|
+
if (escaped) {
|
|
22
|
+
current += char;
|
|
23
|
+
escaped = false;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (char === '\\') {
|
|
28
|
+
escaped = true;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (quoteChar) {
|
|
33
|
+
if (char === quoteChar) {
|
|
34
|
+
quoteChar = null;
|
|
35
|
+
} else {
|
|
36
|
+
current += char;
|
|
37
|
+
}
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (char === '"' || char === "'") {
|
|
42
|
+
quoteChar = char;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (/\s/.test(char)) {
|
|
47
|
+
if (current.length) {
|
|
48
|
+
args.push(current);
|
|
49
|
+
current = '';
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
current += char;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (current.length) {
|
|
58
|
+
args.push(current);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return args;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
class CLIServiceWeb {
|
|
65
|
+
constructor() {
|
|
66
|
+
this.astrologyService = astrologyService;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
_loadConfig() {
|
|
70
|
+
try {
|
|
71
|
+
if (fs.existsSync(CONFIG_PATH)) {
|
|
72
|
+
const configData = fs.readFileSync(CONFIG_PATH, 'utf8');
|
|
73
|
+
return JSON.parse(configData);
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.error('Error loading configuration:', error.message);
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
_saveConfig(config) {
|
|
82
|
+
try {
|
|
83
|
+
const dir = path.posix.dirname(CONFIG_PATH);
|
|
84
|
+
if (!fs.existsSync(dir)) {
|
|
85
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
86
|
+
}
|
|
87
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
88
|
+
return true;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error('Error saving configuration:', error.message);
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
_showConfigStatus() {
|
|
96
|
+
const config = this._loadConfig();
|
|
97
|
+
|
|
98
|
+
if (!config) {
|
|
99
|
+
console.log('Configuration status');
|
|
100
|
+
console.log('======================');
|
|
101
|
+
console.log('No configuration found.');
|
|
102
|
+
console.log('Use --setup in the GUI to configure your location and birth data.');
|
|
103
|
+
return { success: true, output: '' };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log('Configuration status');
|
|
107
|
+
console.log('======================\n');
|
|
108
|
+
|
|
109
|
+
if (config.currentLocation) {
|
|
110
|
+
console.log('Current location:');
|
|
111
|
+
console.log(`Name: ${config.currentLocation.name}, ${config.currentLocation.country}`);
|
|
112
|
+
console.log(`Coordinates: ${config.currentLocation.latitude.toFixed(4)}° latitude, ${config.currentLocation.longitude.toFixed(4)}° longitude`);
|
|
113
|
+
console.log(`Timezone: ${config.currentLocation.timezone}`);
|
|
114
|
+
} else {
|
|
115
|
+
console.log('Current location: Not configured');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
console.log('\nBirth data:');
|
|
119
|
+
if (config.birthData) {
|
|
120
|
+
console.log(`Date: ${config.birthData.date}`);
|
|
121
|
+
console.log(`Time: ${config.birthData.time}`);
|
|
122
|
+
|
|
123
|
+
if (config.birthData.location) {
|
|
124
|
+
console.log(`Birth location: ${config.birthData.location.name}, ${config.birthData.location.country}`);
|
|
125
|
+
console.log(`Birth coordinates: ${config.birthData.location.latitude.toFixed(4)}° latitude, ${config.birthData.location.longitude.toFixed(4)}° longitude`);
|
|
126
|
+
} else {
|
|
127
|
+
console.log('Birth location: Not configured');
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
console.log('Birth data: Not configured');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (config.people && Object.keys(config.people).length > 0) {
|
|
134
|
+
console.log('\nPerson data:');
|
|
135
|
+
console.log('================');
|
|
136
|
+
for (const [personId, personData] of Object.entries(config.people)) {
|
|
137
|
+
console.log(`\nPerson ${personId}:`);
|
|
138
|
+
console.log(` Date: ${personData.date}`);
|
|
139
|
+
console.log(` Time: ${personData.time}`);
|
|
140
|
+
if (personData.location) {
|
|
141
|
+
console.log(` Location: ${personData.location.name}, ${personData.location.country}`);
|
|
142
|
+
console.log(` Coordinates: ${personData.location.latitude.toFixed(4)}° latitude, ${personData.location.longitude.toFixed(4)}° longitude`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
console.log('\nSetup date:');
|
|
148
|
+
if (config.setupDate) {
|
|
149
|
+
console.log(`${new Date(config.setupDate).toLocaleString()}`);
|
|
150
|
+
} else {
|
|
151
|
+
console.log('Not available');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
console.log('\nThis data is used for your personalized astrological calculations.');
|
|
155
|
+
return { success: true, output: '' };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
_showPeople() {
|
|
159
|
+
const config = this._loadConfig();
|
|
160
|
+
if (!config || !config.people || Object.keys(config.people).length === 0) {
|
|
161
|
+
console.log('No people configured.');
|
|
162
|
+
return { success: true, output: '' };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
console.log('Saved people:');
|
|
166
|
+
for (const personId of Object.keys(config.people)) {
|
|
167
|
+
console.log(`- ${personId}`);
|
|
168
|
+
}
|
|
169
|
+
return { success: true, output: '' };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Main command handler
|
|
173
|
+
async handleCommand(planetArg, planet2Arg, options) {
|
|
174
|
+
// If planet2Arg is an object, it contains the options (commander behavior)
|
|
175
|
+
let planet2 = typeof planet2Arg === 'string' ? planet2Arg : null;
|
|
176
|
+
let actualOptions = typeof planet2Arg === 'object' ? planet2Arg : options;
|
|
177
|
+
|
|
178
|
+
// Ensure actualOptions is an object
|
|
179
|
+
if (!actualOptions) {
|
|
180
|
+
actualOptions = {};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Capture output for GUI use
|
|
184
|
+
const output = [];
|
|
185
|
+
const originalConsoleLog = console.log;
|
|
186
|
+
const originalConsoleError = console.error;
|
|
187
|
+
|
|
188
|
+
// Override console methods to capture output
|
|
189
|
+
console.log = (...args) => {
|
|
190
|
+
output.push(args.join(' '));
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
console.error = (...args) => {
|
|
194
|
+
output.push(args.join(' '));
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
if (actualOptions.help || actualOptions.h) {
|
|
199
|
+
console.log('Klio CLI (WebContainer)');
|
|
200
|
+
console.log('Usage: [planet] [options]');
|
|
201
|
+
console.log('');
|
|
202
|
+
console.log('Planets: sun, moon, mars, venus');
|
|
203
|
+
console.log('Options:');
|
|
204
|
+
console.log(' --help, -h Show this help');
|
|
205
|
+
console.log(' --c Critical degrees');
|
|
206
|
+
console.log(' --rx Retrograde planets');
|
|
207
|
+
console.log(' --el Element distribution');
|
|
208
|
+
console.log(' --s All planet positions');
|
|
209
|
+
console.log(' --status Show config');
|
|
210
|
+
console.log(' --people List people');
|
|
211
|
+
console.log(' --setup Setup (GUI only)');
|
|
212
|
+
return { success: true, output: output.join('\n') };
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (actualOptions.setup) {
|
|
216
|
+
console.log('Use --setup in the GUI to configure WebContainer settings.');
|
|
217
|
+
return { success: true, output: output.join('\n') };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (actualOptions.status) {
|
|
221
|
+
this._showConfigStatus();
|
|
222
|
+
return { success: true, output: output.join('\n') };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (actualOptions.people) {
|
|
226
|
+
this._showPeople();
|
|
227
|
+
return { success: true, output: output.join('\n') };
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Show critical planets if --c option is specified
|
|
231
|
+
if (actualOptions.c) {
|
|
232
|
+
const criticalPlanets = this.astrologyService.getCriticalPlanets();
|
|
233
|
+
|
|
234
|
+
if (criticalPlanets.length === 0) {
|
|
235
|
+
console.log('No planets on critical degrees found.');
|
|
236
|
+
return { success: true, output: output.join('\n') };
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
console.log('Critical degrees analysis:');
|
|
240
|
+
console.log('================================================================================');
|
|
241
|
+
console.log('| Planet | Sign | Degree | Type | Interpretation |');
|
|
242
|
+
console.log('================================================================================');
|
|
243
|
+
|
|
244
|
+
criticalPlanets.forEach(planet => {
|
|
245
|
+
const planetName = planet.name.charAt(0).toUpperCase() + planet.name.slice(1);
|
|
246
|
+
const sign = planet.sign.padEnd(10, ' ');
|
|
247
|
+
const degree = planet.degree.padEnd(5, ' ');
|
|
248
|
+
const criticalType = planet.criticalType.padEnd(20, ' ');
|
|
249
|
+
const interpretation = planet.interpretation.padEnd(30, ' ');
|
|
250
|
+
console.log(`| ${planetName.padEnd(8)} | ${sign} | ${degree} | ${criticalType} | ${interpretation} |`);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
console.log('================================================================================');
|
|
254
|
+
|
|
255
|
+
return { success: true, output: output.join('\n') };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Show retrograde planets if --rx option is specified
|
|
259
|
+
if (actualOptions.rx) {
|
|
260
|
+
const retrogradePlanets = this.astrologyService.getRetrogradePlanets();
|
|
261
|
+
|
|
262
|
+
if (retrogradePlanets.length === 0) {
|
|
263
|
+
console.log('No retrograde or stationary planets found.');
|
|
264
|
+
return { success: true, output: output.join('\n') };
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
console.log('Retrograde and stationary planets:');
|
|
268
|
+
console.log('================================================================================');
|
|
269
|
+
console.log('| Planet | Status |');
|
|
270
|
+
console.log('================================================================================');
|
|
271
|
+
|
|
272
|
+
retrogradePlanets.forEach(planet => {
|
|
273
|
+
const planetName = planet.name.charAt(0).toUpperCase() + planet.name.slice(1);
|
|
274
|
+
const status = planet.status.charAt(0).toUpperCase() + planet.status.slice(1);
|
|
275
|
+
console.log(`| ${planetName.padEnd(8)} | ${status.padEnd(10)} |`);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
console.log('================================================================================');
|
|
279
|
+
|
|
280
|
+
return { success: true, output: output.join('\n') };
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Show element distribution if --el option is specified
|
|
284
|
+
if (actualOptions.el) {
|
|
285
|
+
const elementData = this.astrologyService.analyzeElementDistribution();
|
|
286
|
+
|
|
287
|
+
console.log('Element distribution:');
|
|
288
|
+
console.log('================================================================================');
|
|
289
|
+
console.log('| Element | Count |');
|
|
290
|
+
console.log('================================================================================');
|
|
291
|
+
|
|
292
|
+
for (const [element, count] of Object.entries(elementData.elementCounts)) {
|
|
293
|
+
console.log(`| ${element.padEnd(7)} | ${count.toString().padEnd(5)} |`);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
console.log('================================================================================');
|
|
297
|
+
|
|
298
|
+
return { success: true, output: output.join('\n') };
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Show all planet positions if --s option is specified
|
|
302
|
+
if (actualOptions.s) {
|
|
303
|
+
const allPositions = this.astrologyService.getAllPlanetPositions();
|
|
304
|
+
|
|
305
|
+
console.log('Planet positions:');
|
|
306
|
+
console.log('================================================================================');
|
|
307
|
+
console.log('| Planet | Sign | Deg | Dignity | Element |');
|
|
308
|
+
console.log('================================================================================');
|
|
309
|
+
|
|
310
|
+
for (const [planetName, data] of Object.entries(allPositions)) {
|
|
311
|
+
const planetNameFormatted = planetName.charAt(0).toUpperCase() + planetName.slice(1);
|
|
312
|
+
const signFormatted = data.sign.padEnd(10, ' ');
|
|
313
|
+
const degreeFormatted = data.degreeInSign.padEnd(5, ' ');
|
|
314
|
+
const dignityFormatted = data.dignity.padEnd(12, ' ');
|
|
315
|
+
const elementFormatted = data.element.padEnd(9, ' ');
|
|
316
|
+
|
|
317
|
+
console.log(`| ${planetNameFormatted.padEnd(11)} | ${signFormatted} | ${degreeFormatted}° | ${dignityFormatted} | ${elementFormatted} |`);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
console.log('================================================================================');
|
|
321
|
+
|
|
322
|
+
return { success: true, output: output.join('\n') };
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Show normal planet info as default
|
|
326
|
+
const planet = planetArg ? planetArg.toLowerCase() : 'moon';
|
|
327
|
+
const data = this.astrologyService.getAstrologicalData(planet);
|
|
328
|
+
|
|
329
|
+
console.log(`Astrological data for ${data.planet}:`);
|
|
330
|
+
console.log(`Sign: ${data.sign}`);
|
|
331
|
+
console.log(`Degree in sign: ${data.degreeInSign}°`);
|
|
332
|
+
console.log(`Dignity: ${data.dignity}`);
|
|
333
|
+
console.log(`Element: ${data.element}`);
|
|
334
|
+
console.log(`Decan: ${data.decan}`);
|
|
335
|
+
console.log(`Longitude: ${data.longitude}°`);
|
|
336
|
+
|
|
337
|
+
return { success: true, output: output.join('\n') };
|
|
338
|
+
|
|
339
|
+
} catch (error) {
|
|
340
|
+
console.error('Error executing command:', error.message);
|
|
341
|
+
return { success: false, output: output.join('\n') };
|
|
342
|
+
} finally {
|
|
343
|
+
// Restore original console methods
|
|
344
|
+
console.log = originalConsoleLog;
|
|
345
|
+
console.error = originalConsoleError;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Method to execute a command programmatically
|
|
350
|
+
async executeCommand(commandString) {
|
|
351
|
+
// Parse the command string into arguments
|
|
352
|
+
const args = splitCommandArgs(commandString);
|
|
353
|
+
|
|
354
|
+
// Parse options manually
|
|
355
|
+
const options = {};
|
|
356
|
+
const positionalArgs = [];
|
|
357
|
+
|
|
358
|
+
for (let i = 0; i < args.length; i++) {
|
|
359
|
+
const arg = args[i];
|
|
360
|
+
|
|
361
|
+
if (arg.startsWith('--')) {
|
|
362
|
+
// Handle options
|
|
363
|
+
const optionName = arg.substring(2);
|
|
364
|
+
options[optionName] = true;
|
|
365
|
+
} else if (arg.startsWith('-')) {
|
|
366
|
+
// Handle short options
|
|
367
|
+
const optionName = arg.substring(1);
|
|
368
|
+
options[optionName] = true;
|
|
369
|
+
} else {
|
|
370
|
+
// Handle positional arguments
|
|
371
|
+
positionalArgs.push(arg);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const unsupportedOptions = Object.keys(options).filter((option) => !SUPPORTED_OPTIONS.has(option));
|
|
376
|
+
if (unsupportedOptions.length > 0) {
|
|
377
|
+
return {
|
|
378
|
+
success: false,
|
|
379
|
+
output: `Unsupported option(s) in WebContainer: ${unsupportedOptions.join(', ')}`
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (positionalArgs.length > 1) {
|
|
384
|
+
return {
|
|
385
|
+
success: false,
|
|
386
|
+
output: 'Multiple positional arguments are not supported in WebContainer.'
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (positionalArgs[0] && !planets[positionalArgs[0].toLowerCase()]) {
|
|
391
|
+
return {
|
|
392
|
+
success: false,
|
|
393
|
+
output: `Unsupported planet in WebContainer: ${positionalArgs[0]}`
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Create a new instance to handle the command
|
|
398
|
+
const tempService = new CLIServiceWeb();
|
|
399
|
+
const planetArg = positionalArgs[0] || null;
|
|
400
|
+
const planet2Arg = positionalArgs[1] || null;
|
|
401
|
+
|
|
402
|
+
return tempService.handleCommand(planetArg, planet2Arg, options);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
module.exports = new CLIServiceWeb();
|
|
@@ -6,7 +6,10 @@ const readline = require('readline');
|
|
|
6
6
|
const { parseAndFormatMarkdown } = require('../utils/markdownFormatter');
|
|
7
7
|
|
|
8
8
|
// Function to determine cross-platform configuration path
|
|
9
|
-
function getConfigPath() {
|
|
9
|
+
function getConfigPath(userId = null) {
|
|
10
|
+
if (process.env.KLIO_CONFIG_PATH) {
|
|
11
|
+
return process.env.KLIO_CONFIG_PATH;
|
|
12
|
+
}
|
|
10
13
|
let configDir;
|
|
11
14
|
|
|
12
15
|
// Determine configuration directory based on operating system
|
|
@@ -26,6 +29,15 @@ function getConfigPath() {
|
|
|
26
29
|
fs.mkdirSync(configDir, { recursive: true });
|
|
27
30
|
}
|
|
28
31
|
|
|
32
|
+
// For user-specific configs, create user directory
|
|
33
|
+
if (userId) {
|
|
34
|
+
const userDir = path.join(configDir, 'users', userId);
|
|
35
|
+
if (!fs.existsSync(userDir)) {
|
|
36
|
+
fs.mkdirSync(userDir, { recursive: true });
|
|
37
|
+
}
|
|
38
|
+
return path.join(userDir, 'config.json');
|
|
39
|
+
}
|
|
40
|
+
|
|
29
41
|
return path.join(configDir, 'config.json');
|
|
30
42
|
}
|
|
31
43
|
|
|
@@ -82,9 +94,9 @@ async function geocodeLocation(locationName) {
|
|
|
82
94
|
}
|
|
83
95
|
|
|
84
96
|
// Function to save configuration
|
|
85
|
-
function saveConfig(config) {
|
|
97
|
+
function saveConfig(config, userId = null) {
|
|
86
98
|
try {
|
|
87
|
-
const configPath = getConfigPath();
|
|
99
|
+
const configPath = getConfigPath(userId);
|
|
88
100
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
89
101
|
console.log('✓ Configuration successfully saved!');
|
|
90
102
|
console.log(`📁 Location: ${configPath}`);
|
|
@@ -149,7 +161,7 @@ async function parsePersonData(personString) {
|
|
|
149
161
|
}
|
|
150
162
|
|
|
151
163
|
// Function to create/set any person
|
|
152
|
-
async function setPerson(personId, personString) {
|
|
164
|
+
async function setPerson(personId, personString, userId = null) {
|
|
153
165
|
const personData = await parsePersonData(personString);
|
|
154
166
|
|
|
155
167
|
if (!personData) {
|
|
@@ -157,7 +169,7 @@ async function setPerson(personId, personString) {
|
|
|
157
169
|
return false;
|
|
158
170
|
}
|
|
159
171
|
|
|
160
|
-
const config = loadConfig() || {
|
|
172
|
+
const config = loadConfig(userId) || {
|
|
161
173
|
currentLocation: null,
|
|
162
174
|
birthData: null,
|
|
163
175
|
setupDate: new Date().toISOString()
|
|
@@ -172,12 +184,12 @@ async function setPerson(personId, personString) {
|
|
|
172
184
|
config.people[personId] = personData;
|
|
173
185
|
|
|
174
186
|
console.log(`✓ Person "${personId}" successfully created/updated!`);
|
|
175
|
-
return saveConfig(config);
|
|
187
|
+
return saveConfig(config, userId);
|
|
176
188
|
}
|
|
177
189
|
|
|
178
190
|
// Function to load data for a specific person
|
|
179
|
-
function getPersonData(personId) {
|
|
180
|
-
const config = loadConfig();
|
|
191
|
+
function getPersonData(personId, userId = null) {
|
|
192
|
+
const config = loadConfig(userId);
|
|
181
193
|
|
|
182
194
|
if (!config || !config.people || !config.people[personId]) {
|
|
183
195
|
return null;
|
|
@@ -205,8 +217,8 @@ function getPersonData(personId) {
|
|
|
205
217
|
}
|
|
206
218
|
|
|
207
219
|
// Function to list all people
|
|
208
|
-
function listPeople() {
|
|
209
|
-
const config = loadConfig();
|
|
220
|
+
function listPeople(userId = null) {
|
|
221
|
+
const config = loadConfig(userId);
|
|
210
222
|
|
|
211
223
|
if (!config || !config.people || Object.keys(config.people).length === 0) {
|
|
212
224
|
console.log('No people found in configuration.');
|
|
@@ -232,8 +244,8 @@ function listPeople() {
|
|
|
232
244
|
}
|
|
233
245
|
|
|
234
246
|
// Function to delete a person
|
|
235
|
-
function deletePerson(personId) {
|
|
236
|
-
const config = loadConfig();
|
|
247
|
+
function deletePerson(personId, userId = null) {
|
|
248
|
+
const config = loadConfig(userId);
|
|
237
249
|
|
|
238
250
|
if (!config || !config.people || !config.people[personId]) {
|
|
239
251
|
console.error(`Person "${personId}" not found.`);
|
|
@@ -249,26 +261,36 @@ function deletePerson(personId) {
|
|
|
249
261
|
}
|
|
250
262
|
|
|
251
263
|
console.log(`✓ Person "${personId}" successfully deleted!`);
|
|
252
|
-
return saveConfig(config);
|
|
264
|
+
return saveConfig(config, userId);
|
|
253
265
|
}
|
|
254
266
|
|
|
255
267
|
// Function to create/set person 1 (for backward compatibility)
|
|
256
|
-
async function setPerson1(personString) {
|
|
257
|
-
return await setPerson('p1', personString);
|
|
268
|
+
async function setPerson1(personString, userId = null) {
|
|
269
|
+
return await setPerson('p1', personString, userId);
|
|
258
270
|
}
|
|
259
271
|
|
|
260
272
|
// Function to create/set person 2 (for backward compatibility)
|
|
261
|
-
async function setPerson2(personString) {
|
|
262
|
-
return await setPerson('p2', personString);
|
|
273
|
+
async function setPerson2(personString, userId = null) {
|
|
274
|
+
return await setPerson('p2', personString, userId);
|
|
263
275
|
}
|
|
264
276
|
|
|
265
277
|
// Function to load configuration
|
|
266
|
-
function loadConfig() {
|
|
278
|
+
function loadConfig(userId = null) {
|
|
267
279
|
try {
|
|
268
|
-
|
|
269
|
-
|
|
280
|
+
if (process.env.KLIO_CONFIG_JSON) {
|
|
281
|
+
try {
|
|
282
|
+
return JSON.parse(process.env.KLIO_CONFIG_JSON);
|
|
283
|
+
} catch (error) {
|
|
284
|
+
console.error('Error parsing KLIO_CONFIG_JSON:', error.message);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Try to migrate old configuration first (only for global config)
|
|
289
|
+
if (!userId) {
|
|
290
|
+
migrateOldConfig();
|
|
291
|
+
}
|
|
270
292
|
|
|
271
|
-
const configPath = getConfigPath();
|
|
293
|
+
const configPath = getConfigPath(userId);
|
|
272
294
|
if (fs.existsSync(configPath)) {
|
|
273
295
|
const configData = fs.readFileSync(configPath, 'utf8');
|
|
274
296
|
return JSON.parse(configData);
|
|
@@ -280,8 +302,8 @@ function loadConfig() {
|
|
|
280
302
|
}
|
|
281
303
|
|
|
282
304
|
// Function to directly set the AI model
|
|
283
|
-
function setAIModel(modelName) {
|
|
284
|
-
const config = loadConfig() || {
|
|
305
|
+
function setAIModel(modelName, userId = null) {
|
|
306
|
+
const config = loadConfig(userId) || {
|
|
285
307
|
currentLocation: null,
|
|
286
308
|
birthData: null,
|
|
287
309
|
setupDate: new Date().toISOString()
|
|
@@ -297,7 +319,7 @@ function setAIModel(modelName) {
|
|
|
297
319
|
apiKey: null
|
|
298
320
|
};
|
|
299
321
|
|
|
300
|
-
if (saveConfig(config)) {
|
|
322
|
+
if (saveConfig(config, userId)) {
|
|
301
323
|
console.log(`AI model successfully set: ${modelName}`);
|
|
302
324
|
console.log(`Endpoint: ${endpoint}`);
|
|
303
325
|
console.log(`Provider: lm-studio`);
|
|
@@ -307,8 +329,8 @@ function setAIModel(modelName) {
|
|
|
307
329
|
}
|
|
308
330
|
|
|
309
331
|
// Function to set a custom system prompt
|
|
310
|
-
function setSystemPrompt(prompt) {
|
|
311
|
-
const config = loadConfig() || {
|
|
332
|
+
function setSystemPrompt(prompt, userId = null) {
|
|
333
|
+
const config = loadConfig(userId) || {
|
|
312
334
|
currentLocation: null,
|
|
313
335
|
birthData: null,
|
|
314
336
|
setupDate: new Date().toISOString()
|
|
@@ -327,7 +349,7 @@ function setSystemPrompt(prompt) {
|
|
|
327
349
|
// Set the custom system prompt
|
|
328
350
|
config.aiConfiguration.systemPrompt = prompt;
|
|
329
351
|
|
|
330
|
-
if (saveConfig(config)) {
|
|
352
|
+
if (saveConfig(config, userId)) {
|
|
331
353
|
console.log(`System prompt successfully set: "${prompt}"`);
|
|
332
354
|
console.log('This prompt will be used for all future AI requests.');
|
|
333
355
|
return true;
|
|
@@ -336,8 +358,8 @@ function setSystemPrompt(prompt) {
|
|
|
336
358
|
}
|
|
337
359
|
|
|
338
360
|
// Function to display saved configuration
|
|
339
|
-
function showConfigStatus() {
|
|
340
|
-
const config = loadConfig();
|
|
361
|
+
function showConfigStatus(userId = null) {
|
|
362
|
+
const config = loadConfig(userId);
|
|
341
363
|
|
|
342
364
|
if (!config) {
|
|
343
365
|
console.log('Configuration status');
|
|
@@ -410,7 +432,7 @@ function showConfigStatus() {
|
|
|
410
432
|
}
|
|
411
433
|
|
|
412
434
|
// Setup function for location and birth data
|
|
413
|
-
async function performSetup() {
|
|
435
|
+
async function performSetup(userId = null) {
|
|
414
436
|
console.log('AstroCLI Setup Assistant');
|
|
415
437
|
console.log('=========================\n');
|
|
416
438
|
|
|
@@ -547,7 +569,7 @@ async function performSetup() {
|
|
|
547
569
|
};
|
|
548
570
|
|
|
549
571
|
// Save and confirmation
|
|
550
|
-
if (saveConfig(config)) {
|
|
572
|
+
if (saveConfig(config, userId)) {
|
|
551
573
|
console.log('\nPerfect! Your setup is complete!');
|
|
552
574
|
console.log('\nYour configuration:');
|
|
553
575
|
console.log(`- Your location: ${config.currentLocation.name}, ${config.currentLocation.country}`);
|
|
@@ -564,8 +586,8 @@ async function performSetup() {
|
|
|
564
586
|
}
|
|
565
587
|
|
|
566
588
|
// Function to send a question to the AI model
|
|
567
|
-
async function askAIModel(prompt, planetData, houseInfo = null) {
|
|
568
|
-
const config = loadConfig();
|
|
589
|
+
async function askAIModel(prompt, planetData, houseInfo = null, userId = null) {
|
|
590
|
+
const config = loadConfig(userId);
|
|
569
591
|
|
|
570
592
|
if (!config || !config.aiConfiguration) {
|
|
571
593
|
console.log('❌ No AI model configured. Use --setup -ai to configure an AI model.');
|
|
@@ -746,5 +768,7 @@ module.exports = {
|
|
|
746
768
|
setPerson,
|
|
747
769
|
getPersonData,
|
|
748
770
|
listPeople,
|
|
749
|
-
deletePerson
|
|
750
|
-
|
|
771
|
+
deletePerson,
|
|
772
|
+
// Add helper functions for user-specific operations
|
|
773
|
+
getConfigPath
|
|
774
|
+
};
|