hostctl 0.1.48 → 0.1.49
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/README.md +23 -0
- package/dist/bin/hostctl.js +187 -97
- package/dist/bin/hostctl.js.map +1 -1
- package/dist/index.js +187 -97
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2718,7 +2718,7 @@ var Verbosity = {
|
|
|
2718
2718
|
};
|
|
2719
2719
|
|
|
2720
2720
|
// src/version.ts
|
|
2721
|
-
var version = "0.1.
|
|
2721
|
+
var version = "0.1.49";
|
|
2722
2722
|
|
|
2723
2723
|
// src/commands/pkg/create.ts
|
|
2724
2724
|
import { promises as fs5 } from "fs";
|
|
@@ -2942,7 +2942,7 @@ dist/
|
|
|
2942
2942
|
.DS_Store
|
|
2943
2943
|
.env
|
|
2944
2944
|
`;
|
|
2945
|
-
async function createPackage(packageName, options) {
|
|
2945
|
+
async function createPackage(packageName, options, output) {
|
|
2946
2946
|
const resolvedName = expandTildePath(packageName);
|
|
2947
2947
|
const packageDir = path3.isAbsolute(resolvedName) ? resolvedName : path3.join(process.cwd(), resolvedName);
|
|
2948
2948
|
const packageSlug = path3.basename(resolvedName);
|
|
@@ -2965,27 +2965,35 @@ async function createPackage(packageName, options) {
|
|
|
2965
2965
|
await fs5.writeFile(path3.join(packageDir, "README.md"), readmeTemplate(packageJsonName, registryPrefix, false));
|
|
2966
2966
|
await fs5.writeFile(path3.join(packageDir, ".gitignore"), gitignoreTemplate);
|
|
2967
2967
|
}
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
console.log(`1. cd ${packageDir}`);
|
|
2972
|
-
console.log(`2. npm install`);
|
|
2973
|
-
let step = 3;
|
|
2968
|
+
const nextSteps = [];
|
|
2969
|
+
nextSteps.push(`cd ${packageDir}`);
|
|
2970
|
+
nextSteps.push("npm install");
|
|
2974
2971
|
if (options.lang === "typescript") {
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
console.log(`${step}. npm run build`);
|
|
2978
|
-
step += 1;
|
|
2972
|
+
nextSteps.push("Edit src/index.ts and src/tasks/hello.ts to implement your tasks");
|
|
2973
|
+
nextSteps.push("npm run build");
|
|
2979
2974
|
} else {
|
|
2980
|
-
|
|
2981
|
-
step += 1;
|
|
2975
|
+
nextSteps.push("Edit src/index.js and src/tasks/hello.js to implement your tasks");
|
|
2982
2976
|
}
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2977
|
+
nextSteps.push("Test your package with: hostctl tasks .");
|
|
2978
|
+
nextSteps.push(`Run it with: hostctl run . ${registryPrefix}.hello`);
|
|
2979
|
+
if (!output?.quiet) {
|
|
2980
|
+
console.log(`Created new hostctl package '${resolvedName}' at ${packageDir}`);
|
|
2981
|
+
console.log(`
|
|
2982
|
+
Next steps:`);
|
|
2983
|
+
nextSteps.forEach((step, index) => {
|
|
2984
|
+
console.log(`${index + 1}. ${step}`);
|
|
2985
|
+
});
|
|
2986
|
+
console.log(`
|
|
2987
2987
|
Note: The package includes 'hostctl' as a dependency for local development.`);
|
|
2988
|
-
|
|
2988
|
+
console.log(`For production, you may want to add it as a peer dependency instead.`);
|
|
2989
|
+
}
|
|
2990
|
+
return {
|
|
2991
|
+
packageDir,
|
|
2992
|
+
packageName: packageJsonName,
|
|
2993
|
+
registryPrefix,
|
|
2994
|
+
language: options.lang,
|
|
2995
|
+
nextSteps
|
|
2996
|
+
};
|
|
2989
2997
|
}
|
|
2990
2998
|
|
|
2991
2999
|
// src/commands/pkg/package-manager.ts
|
|
@@ -3469,7 +3477,9 @@ var PackageManager = class {
|
|
|
3469
3477
|
this.manifest = { packages: [], version: "1.0" };
|
|
3470
3478
|
}
|
|
3471
3479
|
} catch (error) {
|
|
3472
|
-
|
|
3480
|
+
if (this.app.outputPlain()) {
|
|
3481
|
+
console.warn("Failed to load manifest, creating new one:", error);
|
|
3482
|
+
}
|
|
3473
3483
|
this.manifest = { packages: [], version: "1.0" };
|
|
3474
3484
|
}
|
|
3475
3485
|
}
|
|
@@ -3628,8 +3638,8 @@ var PackageManager = class {
|
|
|
3628
3638
|
const packageToRemove = this.findPackageToRemove(packageIdentifier);
|
|
3629
3639
|
if (!packageToRemove) {
|
|
3630
3640
|
return {
|
|
3631
|
-
success:
|
|
3632
|
-
|
|
3641
|
+
success: true,
|
|
3642
|
+
warning: `Package '${packageIdentifier}' not found. Use 'hostctl pkg list' to see installed packages.`
|
|
3633
3643
|
};
|
|
3634
3644
|
}
|
|
3635
3645
|
await this.removePackageFiles(packageToRemove);
|
|
@@ -3661,7 +3671,9 @@ var PackageManager = class {
|
|
|
3661
3671
|
prefix: packagesDir.toString()
|
|
3662
3672
|
});
|
|
3663
3673
|
} catch (error) {
|
|
3664
|
-
|
|
3674
|
+
if (this.app.outputPlain()) {
|
|
3675
|
+
console.log(`DEBUG: Error during npm uninstall: ${error}`);
|
|
3676
|
+
}
|
|
3665
3677
|
}
|
|
3666
3678
|
}
|
|
3667
3679
|
/**
|
|
@@ -3720,7 +3732,9 @@ var PackageManager = class {
|
|
|
3720
3732
|
const installDir = packagesDir.join(filenamifiedSource);
|
|
3721
3733
|
const existingPackage = this.findPackageBySource(normalizedSource);
|
|
3722
3734
|
if (existingPackage) {
|
|
3723
|
-
|
|
3735
|
+
if (this.app.outputPlain()) {
|
|
3736
|
+
console.log(`Package '${existingPackage.name}' is already installed from ${normalizedSource}`);
|
|
3737
|
+
}
|
|
3724
3738
|
return {
|
|
3725
3739
|
success: true,
|
|
3726
3740
|
packageInfo: existingPackage,
|
|
@@ -3824,7 +3838,9 @@ var PackageManager = class {
|
|
|
3824
3838
|
async findRealInstalledNpmPackagePath(packagesDir, source) {
|
|
3825
3839
|
const nodeModulesPath = packagesDir.join("node_modules");
|
|
3826
3840
|
if (!await nodeModulesPath.exists()) {
|
|
3827
|
-
|
|
3841
|
+
if (this.app.outputPlain()) {
|
|
3842
|
+
console.log(`DEBUG: node_modules does not exist at ${nodeModulesPath.toString()}`);
|
|
3843
|
+
}
|
|
3828
3844
|
return { path: null, name: null };
|
|
3829
3845
|
}
|
|
3830
3846
|
const entries = await fs6.readdir(nodeModulesPath.toString());
|
|
@@ -3865,6 +3881,9 @@ var PackageManager = class {
|
|
|
3865
3881
|
async handleDuplicateNames(finalPackageInfo) {
|
|
3866
3882
|
const actualPackageName = finalPackageInfo.name;
|
|
3867
3883
|
if (this.hasPackageWithName(actualPackageName)) {
|
|
3884
|
+
if (!this.app.outputPlain()) {
|
|
3885
|
+
return;
|
|
3886
|
+
}
|
|
3868
3887
|
const existingPackages = this.getPackagesWithName(actualPackageName);
|
|
3869
3888
|
console.warn(`\u26A0\uFE0F Warning: Package name '${actualPackageName}' already exists.`);
|
|
3870
3889
|
console.warn(` Existing packages:`);
|
|
@@ -3907,91 +3926,102 @@ var PackageManager = class {
|
|
|
3907
3926
|
};
|
|
3908
3927
|
|
|
3909
3928
|
// src/commands/pkg/install.ts
|
|
3910
|
-
async function installPackage(source, app) {
|
|
3929
|
+
async function installPackage(source, app, output) {
|
|
3911
3930
|
const packageManager = new PackageManager(app);
|
|
3912
3931
|
const result = await packageManager.installPackage(source);
|
|
3913
|
-
if (
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3932
|
+
if (!output?.quiet) {
|
|
3933
|
+
if (result.success) {
|
|
3934
|
+
console.log(`Installed package '${result.packageInfo.name}' from ${source} to ${result.installPath}`);
|
|
3935
|
+
} else {
|
|
3936
|
+
console.error(`Failed to install package from ${source}: ${result.error}`);
|
|
3937
|
+
}
|
|
3918
3938
|
}
|
|
3939
|
+
return { ...result, source };
|
|
3919
3940
|
}
|
|
3920
3941
|
|
|
3921
3942
|
// src/commands/pkg/list.ts
|
|
3922
3943
|
import chalk from "chalk";
|
|
3923
3944
|
async function listPackages(app) {
|
|
3924
3945
|
const packageManager = new PackageManager(app);
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3946
|
+
const packages = await packageManager.listPackages();
|
|
3947
|
+
const packagesByName = /* @__PURE__ */ new Map();
|
|
3948
|
+
packages.forEach((pkg) => {
|
|
3949
|
+
if (!packagesByName.has(pkg.name)) {
|
|
3950
|
+
packagesByName.set(pkg.name, []);
|
|
3930
3951
|
}
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
console.log(
|
|
3952
|
+
packagesByName.get(pkg.name).push(pkg);
|
|
3953
|
+
});
|
|
3954
|
+
const duplicateNames = Array.from(packagesByName.entries()).filter(([_, pkgs]) => pkgs.length > 1).map(([name]) => name);
|
|
3955
|
+
return { packages, duplicateNames };
|
|
3956
|
+
}
|
|
3957
|
+
function printPackageList(packages, duplicateNames) {
|
|
3958
|
+
if (packages.length === 0) {
|
|
3959
|
+
console.log("No packages installed.");
|
|
3960
|
+
return;
|
|
3961
|
+
}
|
|
3962
|
+
const packagesByName = /* @__PURE__ */ new Map();
|
|
3963
|
+
packages.forEach((pkg) => {
|
|
3964
|
+
if (!packagesByName.has(pkg.name)) {
|
|
3965
|
+
packagesByName.set(pkg.name, []);
|
|
3966
|
+
}
|
|
3967
|
+
packagesByName.get(pkg.name).push(pkg);
|
|
3968
|
+
});
|
|
3969
|
+
console.log(`Found ${packages.length} package(s):
|
|
3939
3970
|
`);
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3971
|
+
packages.forEach((pkg) => {
|
|
3972
|
+
const packagesWithSameName = packagesByName.get(pkg.name);
|
|
3973
|
+
const hasDuplicates = packagesWithSameName.length > 1;
|
|
3974
|
+
let output = `\u2022 ${pkg.name}`;
|
|
3975
|
+
if (pkg.version) {
|
|
3976
|
+
output += ` (v${pkg.version})`;
|
|
3977
|
+
}
|
|
3978
|
+
if (pkg.description) {
|
|
3979
|
+
output += ` - ${pkg.description}`;
|
|
3980
|
+
}
|
|
3981
|
+
if (hasDuplicates) {
|
|
3982
|
+
output = chalk.yellow(output);
|
|
3983
|
+
output += chalk.yellow(" \u26A0\uFE0F (duplicate name)");
|
|
3984
|
+
}
|
|
3985
|
+
if (pkg.source) {
|
|
3986
|
+
if (pkg.source.startsWith("http") || pkg.source.startsWith("git@")) {
|
|
3987
|
+
output += `
|
|
3957
3988
|
\u{1F4E6} Source: ${pkg.source}`;
|
|
3958
|
-
|
|
3959
|
-
|
|
3989
|
+
} else if (!pkg.source.startsWith(".") && !pkg.source.startsWith("/")) {
|
|
3990
|
+
output += `
|
|
3960
3991
|
\u{1F4E6} Source: https://www.npmjs.com/package/${pkg.source}`;
|
|
3961
|
-
|
|
3962
|
-
|
|
3992
|
+
} else {
|
|
3993
|
+
output += `
|
|
3963
3994
|
\u{1F4E6} Source: ${pkg.source}`;
|
|
3964
|
-
}
|
|
3965
3995
|
}
|
|
3966
|
-
console.log(output);
|
|
3967
|
-
console.log(` \u2514\u2500 (run "hostctl tasks ${pkg.name}" to list tasks)`);
|
|
3968
|
-
console.log("");
|
|
3969
|
-
});
|
|
3970
|
-
const duplicateNames = Array.from(packagesByName.entries()).filter(([_, pkgs]) => pkgs.length > 1).map(([name, _]) => name);
|
|
3971
|
-
if (duplicateNames.length > 0) {
|
|
3972
|
-
console.log(chalk.yellow("\u26A0\uFE0F Warning: The following package names have duplicates:"));
|
|
3973
|
-
duplicateNames.forEach((name) => {
|
|
3974
|
-
console.log(chalk.yellow(` - ${name}`));
|
|
3975
|
-
});
|
|
3976
|
-
console.log(chalk.yellow(" Use the full source URL to run tasks from these packages."));
|
|
3977
|
-
console.log("");
|
|
3978
3996
|
}
|
|
3979
|
-
|
|
3980
|
-
console.
|
|
3981
|
-
|
|
3997
|
+
console.log(output);
|
|
3998
|
+
console.log(` \u2514\u2500 (run "hostctl tasks ${pkg.name}" to list tasks)`);
|
|
3999
|
+
console.log("");
|
|
4000
|
+
});
|
|
4001
|
+
if (duplicateNames.length > 0) {
|
|
4002
|
+
console.log(chalk.yellow("\u26A0\uFE0F Warning: The following package names have duplicates:"));
|
|
4003
|
+
duplicateNames.forEach((name) => {
|
|
4004
|
+
console.log(chalk.yellow(` - ${name}`));
|
|
4005
|
+
});
|
|
4006
|
+
console.log(chalk.yellow(" Use the full source URL to run tasks from these packages."));
|
|
4007
|
+
console.log("");
|
|
3982
4008
|
}
|
|
3983
4009
|
}
|
|
3984
4010
|
|
|
3985
4011
|
// src/commands/pkg/remove.ts
|
|
3986
|
-
async function removePackage(packageIdentifier, app) {
|
|
4012
|
+
async function removePackage(packageIdentifier, app, output) {
|
|
3987
4013
|
const packageManager = new PackageManager(app);
|
|
3988
4014
|
const result = await packageManager.removePackage(packageIdentifier);
|
|
3989
|
-
if (
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
4015
|
+
if (!output?.quiet) {
|
|
4016
|
+
if (result.success && result.packageInfo) {
|
|
4017
|
+
console.log(`Successfully removed package '${result.packageInfo.name}' (${result.packageInfo.directory})`);
|
|
4018
|
+
} else if (result.success && result.warning) {
|
|
4019
|
+
console.warn(result.warning);
|
|
4020
|
+
} else {
|
|
4021
|
+
console.error(`Failed to remove package: ${result.error}`);
|
|
4022
|
+
}
|
|
3994
4023
|
}
|
|
4024
|
+
return result;
|
|
3995
4025
|
}
|
|
3996
4026
|
|
|
3997
4027
|
// src/cli.ts
|
|
@@ -4810,26 +4840,86 @@ var Cli = class {
|
|
|
4810
4840
|
}
|
|
4811
4841
|
}
|
|
4812
4842
|
async handlePkgCreate(packageName, options) {
|
|
4843
|
+
const opts = this.program.opts();
|
|
4844
|
+
if (opts.json) {
|
|
4845
|
+
try {
|
|
4846
|
+
const result = await createPackage(packageName, options, { quiet: true });
|
|
4847
|
+
console.log(JSON.stringify({ success: true, ...result }, null, 2));
|
|
4848
|
+
} catch (error) {
|
|
4849
|
+
console.log(
|
|
4850
|
+
JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error) }, null, 2)
|
|
4851
|
+
);
|
|
4852
|
+
process3.exitCode = 1;
|
|
4853
|
+
}
|
|
4854
|
+
return;
|
|
4855
|
+
}
|
|
4813
4856
|
await createPackage(packageName, options);
|
|
4814
4857
|
}
|
|
4815
4858
|
async handlePkgInstall(source) {
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
console.
|
|
4821
|
-
|
|
4859
|
+
const opts = this.program.opts();
|
|
4860
|
+
await this.loadApp(opts);
|
|
4861
|
+
const result = await installPackage(source, this.app, { quiet: Boolean(opts.json) });
|
|
4862
|
+
if (opts.json) {
|
|
4863
|
+
console.log(
|
|
4864
|
+
JSON.stringify(
|
|
4865
|
+
{
|
|
4866
|
+
success: result.success,
|
|
4867
|
+
source: result.source,
|
|
4868
|
+
package: result.packageInfo,
|
|
4869
|
+
installPath: result.installPath,
|
|
4870
|
+
error: result.error
|
|
4871
|
+
},
|
|
4872
|
+
null,
|
|
4873
|
+
2
|
|
4874
|
+
)
|
|
4822
4875
|
);
|
|
4876
|
+
}
|
|
4877
|
+
if (!result.success) {
|
|
4823
4878
|
process3.exitCode = 1;
|
|
4824
4879
|
}
|
|
4825
4880
|
}
|
|
4826
4881
|
async handlePkgList() {
|
|
4827
|
-
|
|
4828
|
-
await
|
|
4882
|
+
const opts = this.program.opts();
|
|
4883
|
+
await this.loadApp(opts);
|
|
4884
|
+
const result = await listPackages(this.app);
|
|
4885
|
+
if (opts.json) {
|
|
4886
|
+
console.log(
|
|
4887
|
+
JSON.stringify(
|
|
4888
|
+
{
|
|
4889
|
+
count: result.packages.length,
|
|
4890
|
+
duplicates: result.duplicateNames,
|
|
4891
|
+
packages: result.packages
|
|
4892
|
+
},
|
|
4893
|
+
null,
|
|
4894
|
+
2
|
|
4895
|
+
)
|
|
4896
|
+
);
|
|
4897
|
+
return;
|
|
4898
|
+
}
|
|
4899
|
+
printPackageList(result.packages, result.duplicateNames);
|
|
4829
4900
|
}
|
|
4830
4901
|
async handlePkgRemove(packageIdentifier) {
|
|
4831
|
-
|
|
4832
|
-
await
|
|
4902
|
+
const opts = this.program.opts();
|
|
4903
|
+
await this.loadApp(opts);
|
|
4904
|
+
const result = await removePackage(packageIdentifier, this.app, { quiet: Boolean(opts.json) });
|
|
4905
|
+
if (opts.json) {
|
|
4906
|
+
console.log(
|
|
4907
|
+
JSON.stringify(
|
|
4908
|
+
{
|
|
4909
|
+
success: result.success,
|
|
4910
|
+
identifier: packageIdentifier,
|
|
4911
|
+
package: result.packageInfo,
|
|
4912
|
+
error: result.error,
|
|
4913
|
+
warning: result.warning
|
|
4914
|
+
},
|
|
4915
|
+
null,
|
|
4916
|
+
2
|
|
4917
|
+
)
|
|
4918
|
+
);
|
|
4919
|
+
}
|
|
4920
|
+
if (!result.success) {
|
|
4921
|
+
process3.exitCode = 1;
|
|
4922
|
+
}
|
|
4833
4923
|
}
|
|
4834
4924
|
async handleTasksList(specParts, options, cmd) {
|
|
4835
4925
|
const opts = cmd.optsWithGlobals();
|