dhti-cli 1.0.1 → 1.1.0
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/commands/conch.d.ts +2 -1
- package/dist/commands/conch.js +34 -17
- package/dist/commands/elixir.js +136 -50
- package/dist/resources/docker-compose-master.yml +1 -1
- package/oclif.manifest.json +13 -4
- package/package.json +1 -1
package/dist/commands/conch.d.ts
CHANGED
|
@@ -9,8 +9,9 @@ export default class Conch extends Command {
|
|
|
9
9
|
branch: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
10
|
'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
11
|
git: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
local: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
13
|
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
-
sources: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
sources: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
15
|
workdir: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
16
|
};
|
|
16
17
|
run(): Promise<void>;
|
package/dist/commands/conch.js
CHANGED
|
@@ -15,6 +15,7 @@ export default class Conch extends Command {
|
|
|
15
15
|
'<%= config.bin %> <%= command.id %> install -n my-app -w ~/projects',
|
|
16
16
|
'<%= config.bin %> <%= command.id %> init -n my-app -w ~/projects',
|
|
17
17
|
'<%= config.bin %> <%= command.id %> start -n my-app -w ~/projects',
|
|
18
|
+
'<%= config.bin %> <%= command.id %> start -n my-app -w ~/projects -s packages/chatbot -s packages/utils',
|
|
18
19
|
];
|
|
19
20
|
static flags = {
|
|
20
21
|
branch: Flags.string({
|
|
@@ -31,10 +32,15 @@ export default class Conch extends Command {
|
|
|
31
32
|
default: 'dermatologist/openmrs-esm-dhti-template',
|
|
32
33
|
description: 'GitHub repository to install (for install operation)',
|
|
33
34
|
}),
|
|
35
|
+
local: Flags.string({
|
|
36
|
+
char: 'l',
|
|
37
|
+
description: 'Local path to use instead of calculated workdir/name path (for start operation)',
|
|
38
|
+
}),
|
|
34
39
|
name: Flags.string({ char: 'n', description: 'Name of the conch' }),
|
|
35
40
|
sources: Flags.string({
|
|
36
41
|
char: 's',
|
|
37
|
-
description: 'Additional sources to include when starting (e.g., packages/esm-chatbot-agent)',
|
|
42
|
+
description: 'Additional sources to include when starting (e.g., packages/esm-chatbot-agent, packages/esm-another-app)',
|
|
43
|
+
multiple: true,
|
|
38
44
|
}),
|
|
39
45
|
workdir: Flags.string({
|
|
40
46
|
char: 'w',
|
|
@@ -91,21 +97,26 @@ export default class Conch extends Command {
|
|
|
91
97
|
}
|
|
92
98
|
if (args.op === 'start') {
|
|
93
99
|
// Validate required flags
|
|
94
|
-
if (!flags.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
if (!flags.local) {
|
|
101
|
+
// If --local is not provided, require workdir and name
|
|
102
|
+
if (!flags.workdir) {
|
|
103
|
+
console.error(chalk.red('Error: workdir flag is required for start operation (unless --local is provided)'));
|
|
104
|
+
this.exit(1);
|
|
105
|
+
}
|
|
106
|
+
if (!flags.name) {
|
|
107
|
+
console.error(chalk.red('Error: name flag is required for start operation (unless --local is provided)'));
|
|
108
|
+
this.exit(1);
|
|
109
|
+
}
|
|
101
110
|
}
|
|
102
|
-
const targetDir = path.join(flags.workdir, flags.name);
|
|
111
|
+
const targetDir = flags.local || path.join(flags.workdir, flags.name);
|
|
103
112
|
if (flags['dry-run']) {
|
|
104
113
|
console.log(chalk.yellow('[DRY RUN] Would execute start operation:'));
|
|
105
114
|
console.log(chalk.cyan(` cd ${targetDir}`));
|
|
106
115
|
let dryRunCommand = 'corepack enable && yarn install && yarn start';
|
|
107
|
-
if (flags.sources) {
|
|
108
|
-
|
|
116
|
+
if (flags.sources && flags.sources.length > 0) {
|
|
117
|
+
for (const source of flags.sources) {
|
|
118
|
+
dryRunCommand += ` --sources '${source}'`;
|
|
119
|
+
}
|
|
109
120
|
}
|
|
110
121
|
console.log(chalk.cyan(` ${dryRunCommand}`));
|
|
111
122
|
return;
|
|
@@ -113,7 +124,9 @@ export default class Conch extends Command {
|
|
|
113
124
|
// Check if directory exists (not in dry-run mode)
|
|
114
125
|
if (!fs.existsSync(targetDir)) {
|
|
115
126
|
console.error(chalk.red(`Error: Directory does not exist: ${targetDir}`));
|
|
116
|
-
|
|
127
|
+
if (!flags.local) {
|
|
128
|
+
console.log(chalk.yellow(`Run 'dhti-cli conch init -n ${flags.name} -w ${flags.workdir}' first`));
|
|
129
|
+
}
|
|
117
130
|
this.exit(1);
|
|
118
131
|
}
|
|
119
132
|
try {
|
|
@@ -121,8 +134,10 @@ export default class Conch extends Command {
|
|
|
121
134
|
console.log(chalk.yellow('Press Ctrl-C to stop\n'));
|
|
122
135
|
// Build the start command with sources flag if provided
|
|
123
136
|
let startCommand = 'corepack enable && yarn install && yarn start';
|
|
124
|
-
if (flags.sources) {
|
|
125
|
-
|
|
137
|
+
if (flags.sources && flags.sources.length > 0) {
|
|
138
|
+
for (const source of flags.sources) {
|
|
139
|
+
startCommand += ` --sources '${source}'`;
|
|
140
|
+
}
|
|
126
141
|
}
|
|
127
142
|
// Spawn corepack enable && yarn install && yarn start with stdio inheritance to show output and allow Ctrl-C
|
|
128
143
|
const child = spawn(startCommand, {
|
|
@@ -166,7 +181,7 @@ export default class Conch extends Command {
|
|
|
166
181
|
this.exit(1);
|
|
167
182
|
}
|
|
168
183
|
// Warn if sources flag is used with install (not applicable)
|
|
169
|
-
if (flags.sources) {
|
|
184
|
+
if (flags.sources && flags.sources.length > 0) {
|
|
170
185
|
console.warn(chalk.yellow('Warning: --sources flag is not applicable for install operation. It will be ignored.'));
|
|
171
186
|
console.warn(chalk.yellow('Use --sources with the start operation instead.'));
|
|
172
187
|
}
|
|
@@ -185,8 +200,10 @@ export default class Conch extends Command {
|
|
|
185
200
|
console.log(chalk.green(`\n✓ Installation complete! Your app is ready at ${targetDir}`));
|
|
186
201
|
console.log(chalk.blue(`\nTo start development, run:`));
|
|
187
202
|
let startCmd = `dhti-cli conch start -n ${flags.name} -w ${flags.workdir}`;
|
|
188
|
-
if (flags.sources) {
|
|
189
|
-
|
|
203
|
+
if (flags.sources && flags.sources.length > 0) {
|
|
204
|
+
for (const source of flags.sources) {
|
|
205
|
+
startCmd += ` -s '${source}'`;
|
|
206
|
+
}
|
|
190
207
|
}
|
|
191
208
|
console.log(chalk.cyan(` ${startCmd}`));
|
|
192
209
|
}
|
package/dist/commands/elixir.js
CHANGED
|
@@ -299,43 +299,46 @@ export default class Elixir extends Command {
|
|
|
299
299
|
}
|
|
300
300
|
return;
|
|
301
301
|
}
|
|
302
|
-
// Create a directory to install the elixir
|
|
303
|
-
|
|
302
|
+
// Create a directory to install the elixir (only on first install)
|
|
303
|
+
const elixirDir = `${flags.workdir}/elixir`;
|
|
304
|
+
const isFirstInstall = !fs.existsSync(elixirDir);
|
|
305
|
+
if (isFirstInstall) {
|
|
304
306
|
if (flags['dry-run']) {
|
|
305
|
-
console.log(chalk.yellow(`[DRY RUN] Would create directory: ${
|
|
307
|
+
console.log(chalk.yellow(`[DRY RUN] Would create directory: ${elixirDir}`));
|
|
308
|
+
console.log(chalk.yellow(`[DRY RUN] Would copy resources from ${RESOURCES_DIR}/genai to ${elixirDir}`));
|
|
306
309
|
}
|
|
307
310
|
else {
|
|
308
|
-
fs.mkdirSync(
|
|
311
|
+
fs.mkdirSync(elixirDir);
|
|
312
|
+
fs.cpSync(path.join(RESOURCES_DIR, 'genai'), elixirDir, { recursive: true });
|
|
313
|
+
console.log(chalk.blue(`✓ Initialized elixir directory at ${elixirDir}`));
|
|
309
314
|
}
|
|
310
315
|
}
|
|
311
|
-
if (
|
|
312
|
-
console.log(chalk.
|
|
316
|
+
else if (args.op === 'install') {
|
|
317
|
+
console.log(chalk.blue(`Using existing elixir directory at ${elixirDir}`));
|
|
313
318
|
}
|
|
314
|
-
|
|
315
|
-
fs.cpSync(path.join(RESOURCES_DIR, 'genai'), `${flags.workdir}/elixir`, { recursive: true });
|
|
316
|
-
}
|
|
317
|
-
// if whl is not none, copy the whl file to thee whl directory
|
|
319
|
+
// if whl is not none, copy the whl file to the whl directory
|
|
318
320
|
if (flags.whl !== 'none') {
|
|
319
|
-
|
|
321
|
+
const whlDir = `${elixirDir}/whl/`;
|
|
322
|
+
if (!fs.existsSync(whlDir)) {
|
|
320
323
|
if (flags['dry-run']) {
|
|
321
|
-
console.log(chalk.yellow(`[DRY RUN] Would create directory: ${
|
|
324
|
+
console.log(chalk.yellow(`[DRY RUN] Would create directory: ${whlDir}`));
|
|
322
325
|
}
|
|
323
326
|
else {
|
|
324
|
-
fs.mkdirSync(
|
|
327
|
+
fs.mkdirSync(whlDir);
|
|
325
328
|
}
|
|
326
329
|
}
|
|
327
330
|
if (flags['dry-run']) {
|
|
328
|
-
console.log(chalk.yellow(`[DRY RUN] Would copy ${flags.whl} to ${
|
|
329
|
-
console.log(chalk.cyan('[DRY RUN] Installing elixir from whl file. Please modify
|
|
331
|
+
console.log(chalk.yellow(`[DRY RUN] Would copy ${flags.whl} to ${whlDir}${path.basename(flags.whl)}`));
|
|
332
|
+
console.log(chalk.cyan('[DRY RUN] Installing elixir from whl file. Please modify bootstrap.py file if needed'));
|
|
330
333
|
}
|
|
331
334
|
else {
|
|
332
|
-
fs.cpSync(flags.whl, `${
|
|
333
|
-
console.log('Installing elixir from whl file. Please modify
|
|
335
|
+
fs.cpSync(flags.whl, `${whlDir}${path.basename(flags.whl)}`);
|
|
336
|
+
console.log('Installing elixir from whl file. Please modify bootstrap.py file if needed');
|
|
334
337
|
}
|
|
335
338
|
}
|
|
336
339
|
// Install the elixir from git adding to the pyproject.toml file
|
|
337
|
-
|
|
338
|
-
|
|
340
|
+
// Always read from the current state, not the template
|
|
341
|
+
let pyproject = flags['dry-run'] ? '' : fs.readFileSync(`${elixirDir}/pyproject.toml`, 'utf8');
|
|
339
342
|
let lineToAdd = '';
|
|
340
343
|
if (flags.whl !== 'none') {
|
|
341
344
|
lineToAdd = `${flags.name} = { file = "whl/${path.basename(flags.whl)}" }`;
|
|
@@ -366,11 +369,49 @@ export default class Elixir extends Command {
|
|
|
366
369
|
}
|
|
367
370
|
lineToAdd = `${flags.name} = { path = "${absolutePath}" }`;
|
|
368
371
|
}
|
|
372
|
+
// Helper function to add dependency to pyproject.toml
|
|
373
|
+
const addDependencyToPyproject = (content, depName) => {
|
|
374
|
+
// Check if dependency already exists
|
|
375
|
+
if (content.includes(`"${depName}"`)) {
|
|
376
|
+
return content;
|
|
377
|
+
}
|
|
378
|
+
// Add to dependencies array
|
|
379
|
+
return content.replace('dependencies = [', `dependencies = [\n"${depName}",`);
|
|
380
|
+
};
|
|
381
|
+
// Helper function to add source to pyproject.toml
|
|
382
|
+
const addSourceToPyproject = (content, source) => {
|
|
383
|
+
// Check if source already exists (by checking for the package name)
|
|
384
|
+
if (content.includes(`${flags.name} =`)) {
|
|
385
|
+
return content;
|
|
386
|
+
}
|
|
387
|
+
// Add to [tool.uv.sources] section
|
|
388
|
+
return content.replace('[tool.uv.sources]', `[tool.uv.sources]\n${source}\n`);
|
|
389
|
+
};
|
|
390
|
+
// Helper function to remove dependency from pyproject.toml
|
|
391
|
+
const removeDependencyFromPyproject = (content, depName) => {
|
|
392
|
+
// Remove from dependencies array - handle both formats: "depName", or "depName",\n
|
|
393
|
+
let result = content.replace(`"${depName}",`, '').replace(`"${depName}"`, '');
|
|
394
|
+
// Also try to remove with newline variations
|
|
395
|
+
result = result.replace(`\n"${depName}",`, '').replace(`"${depName}",\n`, '');
|
|
396
|
+
return result;
|
|
397
|
+
};
|
|
398
|
+
// Helper function to remove source from pyproject.toml
|
|
399
|
+
const removeSourceFromPyproject = (content, pkgName) => {
|
|
400
|
+
// Remove source line for this package
|
|
401
|
+
const sourceRegex = new RegExp(`${pkgName}\\s*=\\s*\\{[^}]*\\}\n?`, 'g');
|
|
402
|
+
return content.replace(sourceRegex, '');
|
|
403
|
+
};
|
|
404
|
+
let newPyproject = pyproject;
|
|
369
405
|
if (!flags['dry-run']) {
|
|
370
|
-
|
|
371
|
-
|
|
406
|
+
if (args.op === 'install') {
|
|
407
|
+
newPyproject = addDependencyToPyproject(pyproject, flags.name);
|
|
408
|
+
newPyproject = addSourceToPyproject(newPyproject, lineToAdd);
|
|
409
|
+
}
|
|
410
|
+
else if (args.op === 'uninstall') {
|
|
411
|
+
newPyproject = removeDependencyFromPyproject(pyproject, flags.name);
|
|
412
|
+
newPyproject = removeSourceFromPyproject(newPyproject, flags.name);
|
|
413
|
+
}
|
|
372
414
|
}
|
|
373
|
-
const newPyproject = pyproject;
|
|
374
415
|
// Add the elixir import and bootstrap to the server.py file
|
|
375
416
|
let CliImport = `from ${expoName}.bootstrap import bootstrap as ${expoName}_bootstrap\n`;
|
|
376
417
|
CliImport += `${expoName}_bootstrap()\n`;
|
|
@@ -380,54 +421,99 @@ ${expoName}_chain = ${expoName}_chain_class().get_chain_as_langchain_tool()
|
|
|
380
421
|
${expoName}_mcp_tool = ${expoName}_chain_class().get_chain_as_mcp_tool
|
|
381
422
|
mcp_server.add_tool(${expoName}_mcp_tool) # type: ignore
|
|
382
423
|
`;
|
|
383
|
-
let newCliImport = '';
|
|
384
|
-
if (!flags['dry-run']) {
|
|
385
|
-
newCliImport = fs
|
|
386
|
-
.readFileSync(`${flags.workdir}/elixir/app/server.py`, 'utf8')
|
|
387
|
-
.replace('# DHTI_CLI_IMPORT', `#DHTI_CLI_IMPORT\n${CliImport}`);
|
|
388
|
-
}
|
|
389
424
|
const langfuseRoute = `add_routes(app, ${expoName}_chain.with_config(config), path="/langserve/${expoName}")`;
|
|
390
|
-
const newLangfuseRoute = flags['dry-run']
|
|
391
|
-
? ''
|
|
392
|
-
: newCliImport.replace('# DHTI_LANGFUSE_ROUTE', `#DHTI_LANGFUSE_ROUTE\n ${langfuseRoute}`);
|
|
393
425
|
const normalRoute = `add_routes(app, ${expoName}_chain, path="/langserve/${expoName}")`;
|
|
394
|
-
const newNormalRoute = flags['dry-run']
|
|
395
|
-
? ''
|
|
396
|
-
: newLangfuseRoute.replace('# DHTI_NORMAL_ROUTE', `#DHTI_NORMAL_ROUTE\n ${normalRoute}`);
|
|
397
426
|
const commonRoutes = `\nadd_invokes(app, path="/langserve/${expoName}")\nadd_services(app, path="/langserve/${expoName}")`;
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
427
|
+
// Helper function to add elixir to server.py
|
|
428
|
+
// The strategy is to append imports BEFORE the 'import uvicorn' line
|
|
429
|
+
// and append routes AFTER the route marker comments
|
|
430
|
+
const addElixirToServer = (elixirName) => {
|
|
431
|
+
// Read fresh file content each time to get the current state
|
|
432
|
+
const content = flags['dry-run'] ? '' : fs.readFileSync(`${elixirDir}/app/server.py`, 'utf8');
|
|
433
|
+
if (flags['dry-run'] || content === '') {
|
|
434
|
+
return '';
|
|
435
|
+
}
|
|
436
|
+
// Check if elixir already installed
|
|
437
|
+
if (content.includes(`${elixirName}_bootstrap`)) {
|
|
438
|
+
return content;
|
|
439
|
+
}
|
|
440
|
+
let result = content;
|
|
441
|
+
// Find where to insert the import - look for 'import uvicorn' and insert before it
|
|
442
|
+
// This way, all imports are together before uvicorn import
|
|
443
|
+
if (!result.includes('import uvicorn')) {
|
|
444
|
+
console.error(chalk.red('Error: Could not find "import uvicorn" marker in server.py'));
|
|
445
|
+
return content;
|
|
446
|
+
}
|
|
447
|
+
result = result.replace('import uvicorn', `${CliImport}\nimport uvicorn`);
|
|
448
|
+
// For routes, we need to insert into both langfuse and normal route sections
|
|
449
|
+
// But only if they exist
|
|
450
|
+
// Find the langfuse try block and insert before 'except'
|
|
451
|
+
if (result.includes('except:')) {
|
|
452
|
+
// Insert langfuse route before except with proper indentation
|
|
453
|
+
result = result.replace('except:', ` ${langfuseRoute}\n\nexcept:`);
|
|
454
|
+
// Insert normal route in the except block, after the '# DHTI_NORMAL_ROUTE' marker
|
|
455
|
+
result = result.replace('# DHTI_NORMAL_ROUTE\n', `# DHTI_NORMAL_ROUTE\n ${normalRoute}\n`);
|
|
456
|
+
}
|
|
457
|
+
// For common routes, look for the marker and append with proper indentation
|
|
458
|
+
const commonRoutesMarker = '# DHTI_COMMON_ROUTE';
|
|
459
|
+
if (result.includes(commonRoutesMarker)) {
|
|
460
|
+
// Get the exact indentation by checking what comes after the marker
|
|
461
|
+
const markerIndex = result.indexOf(commonRoutesMarker);
|
|
462
|
+
const afterMarker = result.substring(markerIndex + commonRoutesMarker.length);
|
|
463
|
+
const newlineAndIndent = afterMarker.match(/\n[ \t]*/)?.[0] || '\n';
|
|
464
|
+
result = result.replace(commonRoutesMarker, `${commonRoutesMarker}${newlineAndIndent}${commonRoutes}`);
|
|
465
|
+
}
|
|
466
|
+
return result;
|
|
467
|
+
};
|
|
468
|
+
// Helper function to remove elixir from server.py
|
|
469
|
+
const removeElixirFromServer = () => {
|
|
470
|
+
// Read fresh file content each time to get the current state
|
|
471
|
+
const content = flags['dry-run'] ? '' : fs.readFileSync(`${elixirDir}/app/server.py`, 'utf8');
|
|
472
|
+
if (flags['dry-run'] || content === '') {
|
|
473
|
+
return '';
|
|
474
|
+
}
|
|
475
|
+
let result = content;
|
|
476
|
+
result = result.replace(CliImport, '');
|
|
477
|
+
result = result.replace(langfuseRoute, '');
|
|
478
|
+
result = result.replace(normalRoute, '');
|
|
479
|
+
result = result.replace(commonRoutes, '');
|
|
480
|
+
return result;
|
|
481
|
+
};
|
|
482
|
+
let finalRoute = '';
|
|
483
|
+
if (!flags['dry-run'] && args.op === 'install') {
|
|
484
|
+
finalRoute = addElixirToServer(expoName);
|
|
485
|
+
}
|
|
486
|
+
else if (!flags['dry-run'] && args.op === 'uninstall') {
|
|
487
|
+
finalRoute = removeElixirFromServer();
|
|
488
|
+
}
|
|
402
489
|
if (args.op === 'install') {
|
|
403
490
|
if (flags['dry-run']) {
|
|
404
491
|
console.log(chalk.yellow('[DRY RUN] Would update files:'));
|
|
405
|
-
console.log(chalk.cyan(` - ${
|
|
492
|
+
console.log(chalk.cyan(` - ${elixirDir}/pyproject.toml`));
|
|
406
493
|
console.log(chalk.green(` Add dependency: "${flags.name}"`));
|
|
407
494
|
console.log(chalk.green(` Add source: ${lineToAdd}`));
|
|
408
|
-
console.log(chalk.cyan(` - ${
|
|
495
|
+
console.log(chalk.cyan(` - ${elixirDir}/app/server.py`));
|
|
409
496
|
console.log(chalk.green(` Add import and routes for ${expoName}`));
|
|
410
497
|
}
|
|
411
498
|
else {
|
|
412
|
-
fs.writeFileSync(`${
|
|
413
|
-
fs.writeFileSync(`${
|
|
499
|
+
fs.writeFileSync(`${elixirDir}/pyproject.toml`, newPyproject);
|
|
500
|
+
fs.writeFileSync(`${elixirDir}/app/server.py`, finalRoute);
|
|
501
|
+
console.log(chalk.green(`✓ Elixir '${flags.name}' installed successfully`));
|
|
414
502
|
}
|
|
415
503
|
}
|
|
416
504
|
if (args.op === 'uninstall') {
|
|
417
505
|
if (flags['dry-run']) {
|
|
418
506
|
console.log(chalk.yellow('[DRY RUN] Would update files:'));
|
|
419
|
-
console.log(chalk.cyan(` - ${
|
|
507
|
+
console.log(chalk.cyan(` - ${elixirDir}/pyproject.toml`));
|
|
508
|
+
console.log(chalk.green(` Remove dependency: "${flags.name}"`));
|
|
420
509
|
console.log(chalk.green(` Remove source: ${lineToAdd}`));
|
|
421
|
-
console.log(chalk.cyan(` - ${
|
|
510
|
+
console.log(chalk.cyan(` - ${elixirDir}/app/server.py`));
|
|
422
511
|
console.log(chalk.green(` Remove import and routes for ${expoName}`));
|
|
423
512
|
}
|
|
424
513
|
else {
|
|
425
|
-
|
|
426
|
-
fs.writeFileSync(`${
|
|
427
|
-
|
|
428
|
-
newServer = newServer.replace(langfuseRoute, '');
|
|
429
|
-
newServer = newServer.replace(normalRoute, '');
|
|
430
|
-
fs.writeFileSync(`${flags.workdir}/elixir/app/server.py`, newServer);
|
|
514
|
+
fs.writeFileSync(`${elixirDir}/pyproject.toml`, newPyproject);
|
|
515
|
+
fs.writeFileSync(`${elixirDir}/app/server.py`, finalRoute);
|
|
516
|
+
console.log(chalk.green(`✓ Elixir '${flags.name}' uninstalled successfully`));
|
|
431
517
|
}
|
|
432
518
|
}
|
|
433
519
|
}
|
package/oclif.manifest.json
CHANGED
|
@@ -95,7 +95,8 @@
|
|
|
95
95
|
"examples": [
|
|
96
96
|
"<%= config.bin %> <%= command.id %> install -n my-app -w ~/projects",
|
|
97
97
|
"<%= config.bin %> <%= command.id %> init -n my-app -w ~/projects",
|
|
98
|
-
"<%= config.bin %> <%= command.id %> start -n my-app -w ~/projects"
|
|
98
|
+
"<%= config.bin %> <%= command.id %> start -n my-app -w ~/projects",
|
|
99
|
+
"<%= config.bin %> <%= command.id %> start -n my-app -w ~/projects -s packages/chatbot -s packages/utils"
|
|
99
100
|
],
|
|
100
101
|
"flags": {
|
|
101
102
|
"branch": {
|
|
@@ -122,6 +123,14 @@
|
|
|
122
123
|
"multiple": false,
|
|
123
124
|
"type": "option"
|
|
124
125
|
},
|
|
126
|
+
"local": {
|
|
127
|
+
"char": "l",
|
|
128
|
+
"description": "Local path to use instead of calculated workdir/name path (for start operation)",
|
|
129
|
+
"name": "local",
|
|
130
|
+
"hasDynamicHelp": false,
|
|
131
|
+
"multiple": false,
|
|
132
|
+
"type": "option"
|
|
133
|
+
},
|
|
125
134
|
"name": {
|
|
126
135
|
"char": "n",
|
|
127
136
|
"description": "Name of the conch",
|
|
@@ -132,10 +141,10 @@
|
|
|
132
141
|
},
|
|
133
142
|
"sources": {
|
|
134
143
|
"char": "s",
|
|
135
|
-
"description": "Additional sources to include when starting (e.g., packages/esm-chatbot-agent)",
|
|
144
|
+
"description": "Additional sources to include when starting (e.g., packages/esm-chatbot-agent, packages/esm-another-app)",
|
|
136
145
|
"name": "sources",
|
|
137
146
|
"hasDynamicHelp": false,
|
|
138
|
-
"multiple":
|
|
147
|
+
"multiple": true,
|
|
139
148
|
"type": "option"
|
|
140
149
|
},
|
|
141
150
|
"workdir": {
|
|
@@ -796,5 +805,5 @@
|
|
|
796
805
|
]
|
|
797
806
|
}
|
|
798
807
|
},
|
|
799
|
-
"version": "1.0
|
|
808
|
+
"version": "1.1.0"
|
|
800
809
|
}
|