@_davideast/jules-env 0.1.2 → 0.2.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/dist/cli.mjs +381 -17
- package/package.json +7 -2
package/dist/cli.mjs
CHANGED
|
@@ -6029,9 +6029,10 @@ import { spawn } from "node:child_process";
|
|
|
6029
6029
|
import { mkdir, writeFile, appendFile } from "node:fs/promises";
|
|
6030
6030
|
import { resolve, dirname } from "node:path";
|
|
6031
6031
|
import { homedir } from "node:os";
|
|
6032
|
-
|
|
6032
|
+
var SHELLENV_SOURCE = ". $HOME/.jules/shellenv 2>/dev/null; ";
|
|
6033
|
+
async function executePlan(plan, dryRun, label) {
|
|
6033
6034
|
if (dryRun) {
|
|
6034
|
-
console.log(
|
|
6035
|
+
console.log(`--- DRY RUN: ${label ?? "Execution Plan"} ---`);
|
|
6035
6036
|
}
|
|
6036
6037
|
for (const step of plan.installSteps) {
|
|
6037
6038
|
if (dryRun) {
|
|
@@ -6044,7 +6045,8 @@ async function executePlan(plan, dryRun) {
|
|
|
6044
6045
|
console.log(`[${step.id}] ${step.label}...`);
|
|
6045
6046
|
let skip = false;
|
|
6046
6047
|
if (step.checkCmd) {
|
|
6047
|
-
const
|
|
6048
|
+
const fullCheckCmd = `${SHELLENV_SOURCE}${step.checkCmd}`;
|
|
6049
|
+
const check = spawn("sh", ["-c", fullCheckCmd], {
|
|
6048
6050
|
stdio: "ignore"
|
|
6049
6051
|
});
|
|
6050
6052
|
const exitCode = await new Promise((res) => check.on("close", (code) => res(code ?? 1)));
|
|
@@ -6054,7 +6056,8 @@ async function executePlan(plan, dryRun) {
|
|
|
6054
6056
|
}
|
|
6055
6057
|
}
|
|
6056
6058
|
if (!skip) {
|
|
6057
|
-
const
|
|
6059
|
+
const fullCmd = `${SHELLENV_SOURCE}${step.cmd}`;
|
|
6060
|
+
const proc = spawn("sh", ["-c", fullCmd], {
|
|
6058
6061
|
stdio: "inherit"
|
|
6059
6062
|
});
|
|
6060
6063
|
const exitCode = await new Promise((res) => proc.on("close", (code) => res(code ?? 1)));
|
|
@@ -6099,6 +6102,54 @@ async function executePlan(plan, dryRun) {
|
|
|
6099
6102
|
}
|
|
6100
6103
|
}
|
|
6101
6104
|
|
|
6105
|
+
// src/core/resolver.ts
|
|
6106
|
+
class CircularDependencyError extends Error {
|
|
6107
|
+
chain;
|
|
6108
|
+
constructor(chain) {
|
|
6109
|
+
super(`Circular dependency detected: ${chain.join(" -> ")}`);
|
|
6110
|
+
this.chain = chain;
|
|
6111
|
+
this.name = "CircularDependencyError";
|
|
6112
|
+
}
|
|
6113
|
+
}
|
|
6114
|
+
|
|
6115
|
+
class MissingDependencyError extends Error {
|
|
6116
|
+
from;
|
|
6117
|
+
missing;
|
|
6118
|
+
constructor(from, missing) {
|
|
6119
|
+
super(`Recipe '${from}' depends on missing recipe '${missing}'`);
|
|
6120
|
+
this.from = from;
|
|
6121
|
+
this.missing = missing;
|
|
6122
|
+
this.name = "MissingDependencyError";
|
|
6123
|
+
}
|
|
6124
|
+
}
|
|
6125
|
+
function resolveDependencies(recipeName, registry) {
|
|
6126
|
+
const result = [];
|
|
6127
|
+
const visited = new Set;
|
|
6128
|
+
const visiting = new Set;
|
|
6129
|
+
function walk(name, chain) {
|
|
6130
|
+
if (visited.has(name))
|
|
6131
|
+
return;
|
|
6132
|
+
if (visiting.has(name))
|
|
6133
|
+
throw new CircularDependencyError([...chain, name]);
|
|
6134
|
+
const recipe = registry[name];
|
|
6135
|
+
if (!recipe) {
|
|
6136
|
+
if (chain.length > 0) {
|
|
6137
|
+
throw new MissingDependencyError(chain[chain.length - 1], name);
|
|
6138
|
+
}
|
|
6139
|
+
throw new Error(`Recipe '${name}' not found`);
|
|
6140
|
+
}
|
|
6141
|
+
visiting.add(name);
|
|
6142
|
+
for (const dep of recipe.depends ?? []) {
|
|
6143
|
+
walk(dep, [...chain, name]);
|
|
6144
|
+
}
|
|
6145
|
+
visiting.delete(name);
|
|
6146
|
+
visited.add(name);
|
|
6147
|
+
result.push(name);
|
|
6148
|
+
}
|
|
6149
|
+
walk(recipeName, []);
|
|
6150
|
+
return result;
|
|
6151
|
+
}
|
|
6152
|
+
|
|
6102
6153
|
// src/recipes/dart.ts
|
|
6103
6154
|
import { spawnSync } from "node:child_process";
|
|
6104
6155
|
async function resolveDarwin() {
|
|
@@ -6176,6 +6227,304 @@ var DartRecipe = {
|
|
|
6176
6227
|
}
|
|
6177
6228
|
};
|
|
6178
6229
|
|
|
6230
|
+
// src/recipes/flutter.ts
|
|
6231
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
6232
|
+
async function resolveDarwin2() {
|
|
6233
|
+
const installSteps = [
|
|
6234
|
+
{
|
|
6235
|
+
id: "install-flutter",
|
|
6236
|
+
label: "Install Flutter SDK",
|
|
6237
|
+
cmd: "brew install --cask flutter",
|
|
6238
|
+
checkCmd: "brew list --cask flutter"
|
|
6239
|
+
},
|
|
6240
|
+
{
|
|
6241
|
+
id: "precache-web",
|
|
6242
|
+
label: "Precache Flutter web artifacts",
|
|
6243
|
+
cmd: "flutter precache --web",
|
|
6244
|
+
checkCmd: 'test -d "$(brew --cask --room 2>/dev/null || echo /usr/local/Caskroom)/flutter"/*/flutter/bin/cache/flutter_web_sdk'
|
|
6245
|
+
}
|
|
6246
|
+
];
|
|
6247
|
+
let flutterRoot = "";
|
|
6248
|
+
try {
|
|
6249
|
+
const result = spawnSync2("brew", ["--cask", "--room"], { encoding: "utf-8" });
|
|
6250
|
+
if (result.status === 0) {
|
|
6251
|
+
const caskroom = result.stdout.trim();
|
|
6252
|
+
const ls = spawnSync2("ls", [caskroom + "/flutter"], { encoding: "utf-8" });
|
|
6253
|
+
if (ls.status === 0) {
|
|
6254
|
+
const version = ls.stdout.trim().split(`
|
|
6255
|
+
`)[0];
|
|
6256
|
+
if (version) {
|
|
6257
|
+
flutterRoot = `${caskroom}/flutter/${version}/flutter`;
|
|
6258
|
+
}
|
|
6259
|
+
}
|
|
6260
|
+
}
|
|
6261
|
+
} catch (e) {}
|
|
6262
|
+
if (!flutterRoot) {
|
|
6263
|
+
flutterRoot = "/usr/local/Caskroom/flutter/latest/flutter";
|
|
6264
|
+
}
|
|
6265
|
+
installSteps[1].checkCmd = `test -d ${flutterRoot}/bin/cache/flutter_web_sdk`;
|
|
6266
|
+
const env = {
|
|
6267
|
+
FLUTTER_ROOT: flutterRoot
|
|
6268
|
+
};
|
|
6269
|
+
const paths = [
|
|
6270
|
+
`${flutterRoot}/bin`
|
|
6271
|
+
];
|
|
6272
|
+
return ExecutionPlanSchema.parse({ installSteps, env, paths });
|
|
6273
|
+
}
|
|
6274
|
+
async function resolveLinux2() {
|
|
6275
|
+
const installSteps = [
|
|
6276
|
+
{
|
|
6277
|
+
id: "install-flutter-prereqs",
|
|
6278
|
+
label: "Install prerequisites",
|
|
6279
|
+
cmd: "sudo apt-get update && sudo apt-get install -y curl git unzip xz-utils",
|
|
6280
|
+
checkCmd: "dpkg -s curl && dpkg -s git && dpkg -s unzip && dpkg -s xz-utils"
|
|
6281
|
+
},
|
|
6282
|
+
{
|
|
6283
|
+
id: "clone-flutter",
|
|
6284
|
+
label: "Clone Flutter SDK",
|
|
6285
|
+
cmd: "sudo git clone -b stable https://github.com/flutter/flutter.git /usr/local/flutter && sudo chown -R $(id -u):$(id -g) /usr/local/flutter",
|
|
6286
|
+
checkCmd: "test -d /usr/local/flutter"
|
|
6287
|
+
},
|
|
6288
|
+
{
|
|
6289
|
+
id: "precache-web",
|
|
6290
|
+
label: "Precache Flutter web artifacts",
|
|
6291
|
+
cmd: "/usr/local/flutter/bin/flutter precache --web",
|
|
6292
|
+
checkCmd: "test -d /usr/local/flutter/bin/cache/flutter_web_sdk"
|
|
6293
|
+
}
|
|
6294
|
+
];
|
|
6295
|
+
const env = {
|
|
6296
|
+
FLUTTER_ROOT: "/usr/local/flutter"
|
|
6297
|
+
};
|
|
6298
|
+
const paths = [
|
|
6299
|
+
"/usr/local/flutter/bin"
|
|
6300
|
+
];
|
|
6301
|
+
return ExecutionPlanSchema.parse({ installSteps, env, paths });
|
|
6302
|
+
}
|
|
6303
|
+
var FlutterRecipe = {
|
|
6304
|
+
name: "flutter",
|
|
6305
|
+
description: "Flutter SDK (web)",
|
|
6306
|
+
resolve: async (ctx) => {
|
|
6307
|
+
switch (process.platform) {
|
|
6308
|
+
case "darwin":
|
|
6309
|
+
return resolveDarwin2();
|
|
6310
|
+
case "linux":
|
|
6311
|
+
return resolveLinux2();
|
|
6312
|
+
default:
|
|
6313
|
+
throw new Error(`Unsupported platform: ${process.platform}`);
|
|
6314
|
+
}
|
|
6315
|
+
}
|
|
6316
|
+
};
|
|
6317
|
+
|
|
6318
|
+
// src/recipes/ruby.ts
|
|
6319
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
6320
|
+
async function resolveDarwin3() {
|
|
6321
|
+
const installSteps = [{
|
|
6322
|
+
id: "install-ruby",
|
|
6323
|
+
label: "Install Ruby",
|
|
6324
|
+
cmd: "brew install ruby",
|
|
6325
|
+
checkCmd: "brew list --versions ruby"
|
|
6326
|
+
}];
|
|
6327
|
+
let rubyPrefix = "";
|
|
6328
|
+
try {
|
|
6329
|
+
const result = spawnSync3("brew", ["--prefix", "ruby"], { encoding: "utf-8" });
|
|
6330
|
+
if (result.status === 0) {
|
|
6331
|
+
rubyPrefix = result.stdout.trim();
|
|
6332
|
+
}
|
|
6333
|
+
} catch (e) {}
|
|
6334
|
+
if (!rubyPrefix) {
|
|
6335
|
+
rubyPrefix = "/usr/local/opt/ruby";
|
|
6336
|
+
}
|
|
6337
|
+
const env = {
|
|
6338
|
+
GEM_HOME: "$HOME/.gem/ruby"
|
|
6339
|
+
};
|
|
6340
|
+
const paths = [
|
|
6341
|
+
`${rubyPrefix}/bin`,
|
|
6342
|
+
"$HOME/.gem/ruby/bin"
|
|
6343
|
+
];
|
|
6344
|
+
return ExecutionPlanSchema.parse({ installSteps, env, paths });
|
|
6345
|
+
}
|
|
6346
|
+
async function resolveLinux3() {
|
|
6347
|
+
const installSteps = [
|
|
6348
|
+
{
|
|
6349
|
+
id: "install-ruby-prereqs",
|
|
6350
|
+
label: "Install build prerequisites",
|
|
6351
|
+
cmd: "sudo apt-get update && sudo apt-get install -y build-essential",
|
|
6352
|
+
checkCmd: "dpkg -s build-essential"
|
|
6353
|
+
},
|
|
6354
|
+
{
|
|
6355
|
+
id: "install-ruby",
|
|
6356
|
+
label: "Install Ruby",
|
|
6357
|
+
cmd: "sudo apt-get install -y ruby-full",
|
|
6358
|
+
checkCmd: "dpkg -s ruby-full"
|
|
6359
|
+
}
|
|
6360
|
+
];
|
|
6361
|
+
const env = {
|
|
6362
|
+
GEM_HOME: "$HOME/.gem/ruby"
|
|
6363
|
+
};
|
|
6364
|
+
const paths = [
|
|
6365
|
+
"$HOME/.gem/ruby/bin"
|
|
6366
|
+
];
|
|
6367
|
+
return ExecutionPlanSchema.parse({ installSteps, env, paths });
|
|
6368
|
+
}
|
|
6369
|
+
var RubyRecipe = {
|
|
6370
|
+
name: "ruby",
|
|
6371
|
+
description: "Ruby programming language",
|
|
6372
|
+
resolve: async (ctx) => {
|
|
6373
|
+
switch (process.platform) {
|
|
6374
|
+
case "darwin":
|
|
6375
|
+
return resolveDarwin3();
|
|
6376
|
+
case "linux":
|
|
6377
|
+
return resolveLinux3();
|
|
6378
|
+
default:
|
|
6379
|
+
throw new Error(`Unsupported platform: ${process.platform}`);
|
|
6380
|
+
}
|
|
6381
|
+
}
|
|
6382
|
+
};
|
|
6383
|
+
|
|
6384
|
+
// src/recipes/php.ts
|
|
6385
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
6386
|
+
async function resolveDarwin4() {
|
|
6387
|
+
const installSteps = [
|
|
6388
|
+
{
|
|
6389
|
+
id: "install-php",
|
|
6390
|
+
label: "Install PHP",
|
|
6391
|
+
cmd: "brew install php",
|
|
6392
|
+
checkCmd: "brew list --versions php"
|
|
6393
|
+
},
|
|
6394
|
+
{
|
|
6395
|
+
id: "install-composer",
|
|
6396
|
+
label: "Install Composer",
|
|
6397
|
+
cmd: "brew install composer",
|
|
6398
|
+
checkCmd: "brew list --versions composer"
|
|
6399
|
+
}
|
|
6400
|
+
];
|
|
6401
|
+
let phpPrefix = "";
|
|
6402
|
+
try {
|
|
6403
|
+
const result = spawnSync4("brew", ["--prefix", "php"], { encoding: "utf-8" });
|
|
6404
|
+
if (result.status === 0) {
|
|
6405
|
+
phpPrefix = result.stdout.trim();
|
|
6406
|
+
}
|
|
6407
|
+
} catch (e) {}
|
|
6408
|
+
if (!phpPrefix) {
|
|
6409
|
+
phpPrefix = "/usr/local/opt/php";
|
|
6410
|
+
}
|
|
6411
|
+
const env = {
|
|
6412
|
+
COMPOSER_HOME: "$HOME/.config/composer"
|
|
6413
|
+
};
|
|
6414
|
+
const paths = [
|
|
6415
|
+
`${phpPrefix}/bin`,
|
|
6416
|
+
"$HOME/.config/composer/vendor/bin"
|
|
6417
|
+
];
|
|
6418
|
+
return ExecutionPlanSchema.parse({ installSteps, env, paths });
|
|
6419
|
+
}
|
|
6420
|
+
async function resolveLinux4() {
|
|
6421
|
+
const installSteps = [
|
|
6422
|
+
{
|
|
6423
|
+
id: "install-php",
|
|
6424
|
+
label: "Install PHP",
|
|
6425
|
+
cmd: "sudo apt-get update && sudo apt-get install -y php-cli php-common php-mbstring php-xml php-curl php-zip unzip",
|
|
6426
|
+
checkCmd: "dpkg -s php-cli"
|
|
6427
|
+
},
|
|
6428
|
+
{
|
|
6429
|
+
id: "install-composer",
|
|
6430
|
+
label: "Install Composer",
|
|
6431
|
+
cmd: "curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer",
|
|
6432
|
+
checkCmd: "which composer"
|
|
6433
|
+
}
|
|
6434
|
+
];
|
|
6435
|
+
const env = {
|
|
6436
|
+
COMPOSER_HOME: "$HOME/.config/composer"
|
|
6437
|
+
};
|
|
6438
|
+
const paths = [
|
|
6439
|
+
"$HOME/.config/composer/vendor/bin"
|
|
6440
|
+
];
|
|
6441
|
+
return ExecutionPlanSchema.parse({ installSteps, env, paths });
|
|
6442
|
+
}
|
|
6443
|
+
var PhpRecipe = {
|
|
6444
|
+
name: "php",
|
|
6445
|
+
description: "PHP programming language with Composer",
|
|
6446
|
+
resolve: async (ctx) => {
|
|
6447
|
+
switch (process.platform) {
|
|
6448
|
+
case "darwin":
|
|
6449
|
+
return resolveDarwin4();
|
|
6450
|
+
case "linux":
|
|
6451
|
+
return resolveLinux4();
|
|
6452
|
+
default:
|
|
6453
|
+
throw new Error(`Unsupported platform: ${process.platform}`);
|
|
6454
|
+
}
|
|
6455
|
+
}
|
|
6456
|
+
};
|
|
6457
|
+
|
|
6458
|
+
// src/recipes/php-sqlite.ts
|
|
6459
|
+
async function resolveDarwin5() {
|
|
6460
|
+
return ExecutionPlanSchema.parse({ installSteps: [], env: {}, paths: [] });
|
|
6461
|
+
}
|
|
6462
|
+
async function resolveLinux5() {
|
|
6463
|
+
const installSteps = [
|
|
6464
|
+
{
|
|
6465
|
+
id: "install-php-sqlite",
|
|
6466
|
+
label: "Install PHP SQLite extension",
|
|
6467
|
+
cmd: "sudo apt-get update && sudo apt-get install -y php-sqlite3",
|
|
6468
|
+
checkCmd: "dpkg -s php-sqlite3"
|
|
6469
|
+
}
|
|
6470
|
+
];
|
|
6471
|
+
return ExecutionPlanSchema.parse({ installSteps, env: {}, paths: [] });
|
|
6472
|
+
}
|
|
6473
|
+
var PhpSqliteRecipe = {
|
|
6474
|
+
name: "php-sqlite",
|
|
6475
|
+
description: "PHP SQLite extension",
|
|
6476
|
+
depends: ["php"],
|
|
6477
|
+
resolve: async (ctx) => {
|
|
6478
|
+
switch (process.platform) {
|
|
6479
|
+
case "darwin":
|
|
6480
|
+
return resolveDarwin5();
|
|
6481
|
+
case "linux":
|
|
6482
|
+
return resolveLinux5();
|
|
6483
|
+
default:
|
|
6484
|
+
throw new Error(`Unsupported platform: ${process.platform}`);
|
|
6485
|
+
}
|
|
6486
|
+
}
|
|
6487
|
+
};
|
|
6488
|
+
|
|
6489
|
+
// src/recipes/laravel.ts
|
|
6490
|
+
async function resolveDarwin6() {
|
|
6491
|
+
const installSteps = [
|
|
6492
|
+
{
|
|
6493
|
+
id: "install-laravel-installer",
|
|
6494
|
+
label: "Install Laravel installer",
|
|
6495
|
+
cmd: "composer global require laravel/installer",
|
|
6496
|
+
checkCmd: "laravel --version"
|
|
6497
|
+
}
|
|
6498
|
+
];
|
|
6499
|
+
return ExecutionPlanSchema.parse({ installSteps, env: {}, paths: [] });
|
|
6500
|
+
}
|
|
6501
|
+
async function resolveLinux6() {
|
|
6502
|
+
const installSteps = [
|
|
6503
|
+
{
|
|
6504
|
+
id: "install-laravel-installer",
|
|
6505
|
+
label: "Install Laravel installer",
|
|
6506
|
+
cmd: "composer global require laravel/installer",
|
|
6507
|
+
checkCmd: "laravel --version"
|
|
6508
|
+
}
|
|
6509
|
+
];
|
|
6510
|
+
return ExecutionPlanSchema.parse({ installSteps, env: {}, paths: [] });
|
|
6511
|
+
}
|
|
6512
|
+
var LaravelRecipe = {
|
|
6513
|
+
name: "laravel",
|
|
6514
|
+
description: "Laravel PHP framework installer",
|
|
6515
|
+
depends: ["php-sqlite"],
|
|
6516
|
+
resolve: async (ctx) => {
|
|
6517
|
+
switch (process.platform) {
|
|
6518
|
+
case "darwin":
|
|
6519
|
+
return resolveDarwin6();
|
|
6520
|
+
case "linux":
|
|
6521
|
+
return resolveLinux6();
|
|
6522
|
+
default:
|
|
6523
|
+
throw new Error(`Unsupported platform: ${process.platform}`);
|
|
6524
|
+
}
|
|
6525
|
+
}
|
|
6526
|
+
};
|
|
6527
|
+
|
|
6179
6528
|
// src/core/loader.ts
|
|
6180
6529
|
function substituteVars(str, vars) {
|
|
6181
6530
|
return str.replace(/\{\{(\w+)\}\}/g, (_, key) => {
|
|
@@ -6232,13 +6581,13 @@ var ollama_default = {
|
|
|
6232
6581
|
{
|
|
6233
6582
|
id: "enable-ollama",
|
|
6234
6583
|
label: "Enable Ollama service",
|
|
6235
|
-
cmd: "sudo systemctl daemon-reload && sudo systemctl enable --now ollama",
|
|
6236
|
-
checkCmd: "
|
|
6584
|
+
cmd: "if command -v systemctl >/dev/null 2>&1; then sudo systemctl daemon-reload && sudo systemctl enable --now ollama; else nohup ollama serve > /tmp/ollama.log 2>&1 & fi",
|
|
6585
|
+
checkCmd: "curl -sf http://localhost:11434/ >/dev/null 2>&1"
|
|
6237
6586
|
},
|
|
6238
6587
|
{
|
|
6239
6588
|
id: "wait-for-ollama",
|
|
6240
6589
|
label: "Wait for Ollama to initialize",
|
|
6241
|
-
cmd: "sleep
|
|
6590
|
+
cmd: "for i in 1 2 3 4 5 6 7 8 9 10; do curl -sf http://localhost:11434/ >/dev/null 2>&1 && exit 0; sleep 1; done; echo 'Ollama server did not start'; exit 1"
|
|
6242
6591
|
},
|
|
6243
6592
|
{
|
|
6244
6593
|
id: "pull-model",
|
|
@@ -6255,7 +6604,7 @@ var ollama_default = {
|
|
|
6255
6604
|
// package.json
|
|
6256
6605
|
var package_default = {
|
|
6257
6606
|
name: "@_davideast/jules-env",
|
|
6258
|
-
version: "0.1
|
|
6607
|
+
version: "0.2.1",
|
|
6259
6608
|
description: "Configure ephemeral development environments",
|
|
6260
6609
|
license: "Apache-2.0",
|
|
6261
6610
|
type: "module",
|
|
@@ -6288,7 +6637,12 @@ var package_default = {
|
|
|
6288
6637
|
test: "bun test",
|
|
6289
6638
|
typecheck: "tsc --noEmit",
|
|
6290
6639
|
"check:all": "bun run scripts/prepublish-checks.ts",
|
|
6291
|
-
prepack: "bun run scripts/prepublish-checks.ts"
|
|
6640
|
+
prepack: "bun run scripts/prepublish-checks.ts",
|
|
6641
|
+
docker: "docker build -t jules-env . && docker run --rm -it jules-env",
|
|
6642
|
+
"test:install": "./scripts/test-install.sh"
|
|
6643
|
+
},
|
|
6644
|
+
np: {
|
|
6645
|
+
"2fa": false
|
|
6292
6646
|
}
|
|
6293
6647
|
};
|
|
6294
6648
|
|
|
@@ -6296,28 +6650,38 @@ var package_default = {
|
|
|
6296
6650
|
var program2 = new Command;
|
|
6297
6651
|
var recipes = {
|
|
6298
6652
|
dart: DartRecipe,
|
|
6653
|
+
flutter: FlutterRecipe,
|
|
6654
|
+
ruby: RubyRecipe,
|
|
6655
|
+
php: PhpRecipe,
|
|
6656
|
+
"php-sqlite": PhpSqliteRecipe,
|
|
6657
|
+
laravel: LaravelRecipe,
|
|
6299
6658
|
ollama: loadDataRecipe(ollama_default)
|
|
6300
6659
|
};
|
|
6301
6660
|
program2.name("jules-env").description("Configure ephemeral development environments").version(package_default.version);
|
|
6302
6661
|
program2.command("use <runtime>").description("Setup a runtime environment").option("--version <v>", "Version to install", "latest").option("--dry-run", "Simulate execution", false).option("--preset <p>", "Configuration preset").action(async (runtime, options) => {
|
|
6303
6662
|
try {
|
|
6304
|
-
const recipe = recipes[runtime];
|
|
6305
|
-
if (!recipe) {
|
|
6306
|
-
console.error(`Error: Recipe for '${runtime}' not found.`);
|
|
6307
|
-
process.exit(1);
|
|
6308
|
-
}
|
|
6309
6663
|
const context = UseContextSchema.parse({
|
|
6310
6664
|
runtime,
|
|
6311
6665
|
version: options.version,
|
|
6312
6666
|
preset: options.preset,
|
|
6313
6667
|
dryRun: options.dryRun
|
|
6314
6668
|
});
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6669
|
+
const order = resolveDependencies(runtime, recipes);
|
|
6670
|
+
if (order.length > 1) {
|
|
6671
|
+
console.log(`[jules-env] Resolving dependencies: ${order.join(" -> ")}`);
|
|
6672
|
+
}
|
|
6673
|
+
for (const recipeName of order) {
|
|
6674
|
+
const recipe = recipes[recipeName];
|
|
6675
|
+
const depContext = recipeName === runtime ? context : UseContextSchema.parse({ runtime: recipeName, dryRun: context.dryRun });
|
|
6676
|
+
console.log(`[jules-env] Resolving plan for ${recipeName}...`);
|
|
6677
|
+
const plan = await recipe.resolve(depContext);
|
|
6678
|
+
await executePlan(plan, context.dryRun, recipeName);
|
|
6679
|
+
}
|
|
6318
6680
|
} catch (err) {
|
|
6319
6681
|
if (err instanceof z.ZodError) {
|
|
6320
6682
|
console.error("Validation Error:", err.errors);
|
|
6683
|
+
} else if (err instanceof CircularDependencyError || err instanceof MissingDependencyError) {
|
|
6684
|
+
console.error("Dependency Error:", err.message);
|
|
6321
6685
|
} else {
|
|
6322
6686
|
console.error("Error:", err);
|
|
6323
6687
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@_davideast/jules-env",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Configure ephemeral development environments",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -33,6 +33,11 @@
|
|
|
33
33
|
"test": "bun test",
|
|
34
34
|
"typecheck": "tsc --noEmit",
|
|
35
35
|
"check:all": "bun run scripts/prepublish-checks.ts",
|
|
36
|
-
"prepack": "bun run scripts/prepublish-checks.ts"
|
|
36
|
+
"prepack": "bun run scripts/prepublish-checks.ts",
|
|
37
|
+
"docker": "docker build -t jules-env . && docker run --rm -it jules-env",
|
|
38
|
+
"test:install": "./scripts/test-install.sh"
|
|
39
|
+
},
|
|
40
|
+
"np": {
|
|
41
|
+
"2fa": false
|
|
37
42
|
}
|
|
38
43
|
}
|