@hanzogui/get 8.3.1 → 8.3.3
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/cjs/cli.js +62 -0
- package/dist/cjs/cli.js.map +1 -0
- package/dist/cjs/commands/add.js +20 -0
- package/dist/cjs/commands/add.js.map +1 -0
- package/dist/cjs/commands/init.js +19 -0
- package/dist/cjs/commands/init.js.map +1 -0
- package/dist/cjs/commands/list.js +24 -0
- package/dist/cjs/commands/list.js.map +1 -0
- package/dist/cjs/commands/pick.js +56 -0
- package/dist/cjs/commands/pick.js.map +1 -0
- package/dist/cjs/constants.js +5 -0
- package/dist/cjs/constants.js.map +1 -0
- package/dist/cjs/lib/ansi.js +14 -0
- package/dist/cjs/lib/ansi.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/cli.js +61 -0
- package/dist/esm/cli.js.map +1 -0
- package/dist/esm/commands/add.js +17 -0
- package/dist/esm/commands/add.js.map +1 -0
- package/dist/esm/commands/init.js +15 -0
- package/dist/esm/commands/init.js.map +1 -0
- package/dist/esm/commands/list.js +21 -0
- package/dist/esm/commands/list.js.map +1 -0
- package/dist/esm/commands/pick.js +52 -0
- package/dist/esm/commands/pick.js.map +1 -0
- package/dist/esm/constants.js +2 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/lib/ansi.js +11 -0
- package/dist/esm/lib/ansi.js.map +1 -0
- package/package.json +19 -13
- package/src/cli.ts +1 -0
- package/src/commands/init.test.ts +44 -0
- package/src/lib/ansi.test.ts +12 -0
- package/types/cli.d.ts +3 -0
- package/types/cli.d.ts.map +1 -0
- package/types/commands/add.d.ts +2 -0
- package/types/commands/add.d.ts.map +1 -0
- package/types/commands/init.d.ts +2 -0
- package/types/commands/init.d.ts.map +1 -0
- package/types/commands/list.d.ts +2 -0
- package/types/commands/list.d.ts.map +1 -0
- package/types/commands/pick.d.ts +2 -0
- package/types/commands/pick.d.ts.map +1 -0
- package/types/constants.d.ts +2 -0
- package/types/constants.d.ts.map +1 -0
- package/types/lib/ansi.d.ts +8 -0
- package/types/lib/ansi.d.ts.map +1 -0
- package/dist/cli.js +0 -1703
package/dist/cjs/cli.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const constants_js_1 = require("./constants.js");
|
|
6
|
+
const ansi_js_1 = require("./lib/ansi.js");
|
|
7
|
+
const HELP = `${constants_js_1.CLI_NAME} — install Hanzo GUI recipes into your project.
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
${constants_js_1.CLI_NAME} Interactive picker.
|
|
11
|
+
${constants_js_1.CLI_NAME} add <slug> Install a single recipe.
|
|
12
|
+
${constants_js_1.CLI_NAME} list List all available recipes.
|
|
13
|
+
${constants_js_1.CLI_NAME} init Write gui.config.json.
|
|
14
|
+
${constants_js_1.CLI_NAME} --help Show this message.
|
|
15
|
+
${constants_js_1.CLI_NAME} --version Print version.
|
|
16
|
+
|
|
17
|
+
Recipes are fetched from Hanzo Base at $HANZO_BASE_URL (default https://base.hanzo.ai).
|
|
18
|
+
Recipe files vendor into src/gui/ by default; override via gui.config.json.
|
|
19
|
+
`;
|
|
20
|
+
async function main() {
|
|
21
|
+
const [, , cmd, ...rest] = process.argv;
|
|
22
|
+
if (cmd === '--help' || cmd === '-h' || cmd === 'help') {
|
|
23
|
+
process.stdout.write(HELP);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (cmd === '--version' || cmd === '-v') {
|
|
27
|
+
const pkg = await Promise.resolve().then(() => tslib_1.__importStar(require('../package.json')));
|
|
28
|
+
process.stdout.write((pkg.default?.version ?? 'unknown') + '\n');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (!cmd) {
|
|
32
|
+
const { pick } = await Promise.resolve().then(() => tslib_1.__importStar(require('./commands/pick.js')));
|
|
33
|
+
await pick();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (cmd === 'add') {
|
|
37
|
+
if (!rest[0]) {
|
|
38
|
+
process.stderr.write(`Usage: ${constants_js_1.CLI_NAME} add <recipe-slug>\n`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
const { add } = await Promise.resolve().then(() => tslib_1.__importStar(require('./commands/add.js')));
|
|
42
|
+
await add(rest[0]);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (cmd === 'list') {
|
|
46
|
+
const { list } = await Promise.resolve().then(() => tslib_1.__importStar(require('./commands/list.js')));
|
|
47
|
+
await list();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (cmd === 'init') {
|
|
51
|
+
const { init } = await Promise.resolve().then(() => tslib_1.__importStar(require('./commands/init.js')));
|
|
52
|
+
await init();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
process.stderr.write(`Unknown command: ${cmd}\n\n${HELP}`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
main().catch((e) => {
|
|
59
|
+
process.stderr.write((0, ansi_js_1.red)(e instanceof Error ? e.message : String(e)) + '\n');
|
|
60
|
+
process.exit(1);
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";;;;AACA,iDAAyC;AACzC,2CAAmC;AAEnC,MAAM,IAAI,GAAG,GAAG,uBAAQ;;;IAGpB,uBAAQ;IACR,uBAAQ;IACR,uBAAQ;IACR,uBAAQ;IACR,uBAAQ;IACR,uBAAQ;;;;CAIX,CAAA;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,CAAC,EAAE,AAAD,EAAG,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAA;IAEvC,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC1B,OAAM;IACR,CAAC;IAED,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,gEAAa,iBAAiB,GAEnB,CAAA;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,CAAE,GAA0C,CAAC,OAAO,EAAE,OAAO,IAAI,SAAS,CAAC,GAAG,IAAI,CACnF,CAAA;QACD,OAAM;IACR,CAAC;IAED,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,EAAE,IAAI,EAAE,GAAG,gEAAa,oBAAoB,GAAC,CAAA;QACnD,MAAM,IAAI,EAAE,CAAA;QACZ,OAAM;IACR,CAAC;IAED,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,uBAAQ,sBAAsB,CAAC,CAAA;YAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QACD,MAAM,EAAE,GAAG,EAAE,GAAG,gEAAa,mBAAmB,GAAC,CAAA;QACjD,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QAClB,OAAM;IACR,CAAC;IAED,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACnB,MAAM,EAAE,IAAI,EAAE,GAAG,gEAAa,oBAAoB,GAAC,CAAA;QACnD,MAAM,IAAI,EAAE,CAAA;QACZ,OAAM;IACR,CAAC;IAED,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACnB,MAAM,EAAE,IAAI,EAAE,GAAG,gEAAa,oBAAoB,GAAC,CAAA;QACnD,MAAM,IAAI,EAAE,CAAA;QACZ,OAAM;IACR,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,GAAG,OAAO,IAAI,EAAE,CAAC,CAAA;IAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAA,aAAG,EAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.add = add;
|
|
4
|
+
const recipes_1 = require("@hanzogui/recipes");
|
|
5
|
+
const ansi_js_1 = require("../lib/ansi.js");
|
|
6
|
+
async function add(slug) {
|
|
7
|
+
const plan = await (0, recipes_1.resolveRecipe)(slug);
|
|
8
|
+
const paths = await (0, recipes_1.installPlan)(plan);
|
|
9
|
+
process.stdout.write((0, ansi_js_1.green)(`Installed "${plan.recipe.name}"`) + '\n');
|
|
10
|
+
if (plan.transitiveRecipes.length > 0) {
|
|
11
|
+
process.stdout.write((0, ansi_js_1.gray)(`+ ${plan.transitiveRecipes.length} dependent recipe${plan.transitiveRecipes.length === 1 ? '' : 's'}: ${plan.transitiveRecipes.map((r) => r.slug).join(', ')}\n`));
|
|
12
|
+
}
|
|
13
|
+
for (const p of paths)
|
|
14
|
+
process.stdout.write(` ${p}\n`);
|
|
15
|
+
if (plan.recipe.npmDeps.length > 0) {
|
|
16
|
+
process.stdout.write('\n' + (0, ansi_js_1.gray)('Install these npm deps:') + '\n');
|
|
17
|
+
process.stdout.write(` ${(0, ansi_js_1.bold)('npm i ' + plan.recipe.npmDeps.join(' '))}\n`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/commands/add.ts"],"names":[],"mappings":";;;AAAA,+CAA8D;AAC9D,4CAAkD;AAE3C,KAAK,cAAc,IAAY;IACpC,MAAM,IAAI,GAAG,MAAM,IAAA,uBAAa,EAAC,IAAI,CAAC,CAAA;IACtC,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAW,EAAC,IAAI,CAAC,CAAA;IAErC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAA,eAAK,EAAC,cAAc,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;IACrE,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAA,cAAI,EACF,KAAK,IAAI,CAAC,iBAAiB,CAAC,MAAM,oBAChC,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAC7C,KAAK,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAC9D,CACF,CAAA;IACH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACvD,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAA,cAAI,EAAC,yBAAyB,CAAC,GAAG,IAAI,CAAC,CAAA;QACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAA,cAAI,EAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAA;IAC/E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.init = init;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
7
|
+
const recipes_1 = require("@hanzogui/recipes");
|
|
8
|
+
const ansi_js_1 = require("../lib/ansi.js");
|
|
9
|
+
async function init() {
|
|
10
|
+
const root = await (0, recipes_1.findProjectRoot)();
|
|
11
|
+
const dest = node_path_1.default.join(root, 'gui.config.json');
|
|
12
|
+
if ((0, node_fs_1.existsSync)(dest)) {
|
|
13
|
+
process.stdout.write((0, ansi_js_1.yellow)(`gui.config.json already exists at ${dest}\n`));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
await node_fs_1.promises.writeFile(dest, JSON.stringify({ installDir: recipes_1.DEFAULT_INSTALL_DIR }, null, 2) + '\n');
|
|
17
|
+
process.stdout.write((0, ansi_js_1.green)(`Wrote ${dest}\n`));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":";;;;AAAA,qCAAoD;AACpD,kEAA4B;AAC5B,+CAAwE;AACxE,4CAA8C;AAEvC,KAAK;IACV,MAAM,IAAI,GAAG,MAAM,IAAA,yBAAe,GAAE,CAAA;IACpC,MAAM,IAAI,GAAG,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAA;IAC/C,IAAI,IAAA,oBAAU,EAAC,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAA,gBAAM,EAAC,qCAAqC,IAAI,IAAI,CAAC,CAAC,CAAA;QAC3E,OAAM;IACR,CAAC;IACD,MAAM,kBAAE,CAAC,SAAS,CAChB,IAAI,EACJ,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,6BAAmB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CACpE,CAAA;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAA,eAAK,EAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAA;AAChD,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.list = list;
|
|
4
|
+
const recipes_1 = require("@hanzogui/recipes");
|
|
5
|
+
const ansi_js_1 = require("../lib/ansi.js");
|
|
6
|
+
async function list() {
|
|
7
|
+
var _a;
|
|
8
|
+
const recipes = await (0, recipes_1.listRecipes)();
|
|
9
|
+
if (recipes.length === 0) {
|
|
10
|
+
process.stdout.write((0, ansi_js_1.yellow)('No recipes published yet.\n'));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const byCategory = {};
|
|
14
|
+
for (const r of recipes)
|
|
15
|
+
(byCategory[_a = r.category || 'misc'] || (byCategory[_a] = [])).push(r);
|
|
16
|
+
for (const [cat, items] of Object.entries(byCategory)) {
|
|
17
|
+
process.stdout.write(`\n${(0, ansi_js_1.bold)(cat)}\n`);
|
|
18
|
+
for (const r of items) {
|
|
19
|
+
process.stdout.write(` ${(0, ansi_js_1.cyan)(r.slug.padEnd(24))} ${(0, ansi_js_1.gray)(r.description)}\n`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
process.stdout.write('\n');
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/list.ts"],"names":[],"mappings":";;;AAAA,+CAA+C;AAC/C,4CAAyD;AAElD,KAAK;;IACV,MAAM,OAAO,GAAG,MAAM,IAAA,qBAAW,GAAE,CAAA;IACnC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAA,gBAAM,EAAC,6BAA6B,CAAC,CAAC,CAAA;QAC3D,OAAM;IACR,CAAC;IACD,MAAM,UAAU,GAAmC,EAAE,CAAA;IACrD,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,CAAC,UAAU,MAAC,CAAC,CAAC,QAAQ,IAAI,MAAM,MAA/B,UAAU,OAA2B,EAAE,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1E,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAA,cAAI,EAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACxC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAA,cAAI,EAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,IAAA,cAAI,EAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QAChF,CAAC;IACH,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pick = pick;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fuse_js_1 = tslib_1.__importDefault(require("fuse.js"));
|
|
6
|
+
const readline = tslib_1.__importStar(require("node:readline/promises"));
|
|
7
|
+
const recipes_1 = require("@hanzogui/recipes");
|
|
8
|
+
const ansi_js_1 = require("../lib/ansi.js");
|
|
9
|
+
const add_js_1 = require("./add.js");
|
|
10
|
+
async function pick() {
|
|
11
|
+
const recipes = await (0, recipes_1.listRecipes)();
|
|
12
|
+
if (recipes.length === 0) {
|
|
13
|
+
process.stdout.write('No recipes published yet.\n');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const fuse = new fuse_js_1.default(recipes, {
|
|
17
|
+
keys: ['name', 'slug', 'category', 'description'],
|
|
18
|
+
threshold: 0.4,
|
|
19
|
+
});
|
|
20
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
21
|
+
try {
|
|
22
|
+
const query = (await rl.question((0, ansi_js_1.bold)('Search recipes') + ' (empty = show all): ')).trim();
|
|
23
|
+
const hits = query ? fuse.search(query).map((h) => h.item) : recipes;
|
|
24
|
+
if (hits.length === 0) {
|
|
25
|
+
process.stdout.write((0, ansi_js_1.dim)('No matches.\n'));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
process.stdout.write('\n');
|
|
29
|
+
hits.slice(0, 20).forEach((r, i) => {
|
|
30
|
+
process.stdout.write(` ${(0, ansi_js_1.cyan)(String(i + 1).padStart(2))} ${(0, ansi_js_1.bold)(r.name)} ${(0, ansi_js_1.gray)(r.slug)}\n`);
|
|
31
|
+
process.stdout.write(` ${(0, ansi_js_1.gray)(r.description)}\n`);
|
|
32
|
+
});
|
|
33
|
+
process.stdout.write('\n');
|
|
34
|
+
const pickRaw = (await rl.question('Pick a number (or paste a slug): ')).trim();
|
|
35
|
+
if (!pickRaw)
|
|
36
|
+
return;
|
|
37
|
+
let slug;
|
|
38
|
+
const asNum = Number.parseInt(pickRaw, 10);
|
|
39
|
+
if (!Number.isNaN(asNum) && asNum >= 1 && asNum <= hits.length) {
|
|
40
|
+
slug = hits[asNum - 1].slug;
|
|
41
|
+
}
|
|
42
|
+
else if (recipes.find((r) => r.slug === pickRaw)) {
|
|
43
|
+
slug = pickRaw;
|
|
44
|
+
}
|
|
45
|
+
if (!slug) {
|
|
46
|
+
process.stdout.write((0, ansi_js_1.dim)(`No recipe matches "${pickRaw}".\n`));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
process.stdout.write('\n');
|
|
50
|
+
await (0, add_js_1.add)(slug);
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
rl.close();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=pick.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pick.js","sourceRoot":"","sources":["../../../src/commands/pick.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,QAAQ,GAAG,eAAe,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.gray = exports.cyan = exports.yellow = exports.green = exports.red = exports.dim = exports.bold = void 0;
|
|
4
|
+
const ESC = '\x1b[';
|
|
5
|
+
const isTTY = process.stdout.isTTY === true;
|
|
6
|
+
const wrap = (open, close) => (s) => isTTY ? `${ESC}${open}m${s}${ESC}${close}m` : s;
|
|
7
|
+
exports.bold = wrap(1, 22);
|
|
8
|
+
exports.dim = wrap(2, 22);
|
|
9
|
+
exports.red = wrap(31, 39);
|
|
10
|
+
exports.green = wrap(32, 39);
|
|
11
|
+
exports.yellow = wrap(33, 39);
|
|
12
|
+
exports.cyan = wrap(36, 39);
|
|
13
|
+
exports.gray = wrap(90, 39);
|
|
14
|
+
//# sourceMappingURL=ansi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ansi.js","sourceRoot":"","sources":["../../../src/lib/ansi.ts"],"names":[],"mappings":";;;AAAA,MAAM,GAAG,GAAG,OAAO,CAAA;AACnB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAA;AAC3C,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE,CAAC,CAAC,CAAS,EAAE,EAAE,CAC1D,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;AAEpC,QAAA,IAAI,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAClB,QAAA,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AACjB,QAAA,GAAG,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;AAClB,QAAA,KAAK,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;AACpB,QAAA,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;AACrB,QAAA,IAAI,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;AACnB,QAAA,IAAI,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "type": "commonjs" }
|
package/dist/esm/cli.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { CLI_NAME } from './constants.js';
|
|
3
|
+
import { red } from './lib/ansi.js';
|
|
4
|
+
const HELP = `${CLI_NAME} — install Hanzo GUI recipes into your project.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
${CLI_NAME} Interactive picker.
|
|
8
|
+
${CLI_NAME} add <slug> Install a single recipe.
|
|
9
|
+
${CLI_NAME} list List all available recipes.
|
|
10
|
+
${CLI_NAME} init Write gui.config.json.
|
|
11
|
+
${CLI_NAME} --help Show this message.
|
|
12
|
+
${CLI_NAME} --version Print version.
|
|
13
|
+
|
|
14
|
+
Recipes are fetched from Hanzo Base at $HANZO_BASE_URL (default https://base.hanzo.ai).
|
|
15
|
+
Recipe files vendor into src/gui/ by default; override via gui.config.json.
|
|
16
|
+
`;
|
|
17
|
+
async function main() {
|
|
18
|
+
const [, , cmd, ...rest] = process.argv;
|
|
19
|
+
if (cmd === '--help' || cmd === '-h' || cmd === 'help') {
|
|
20
|
+
process.stdout.write(HELP);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (cmd === '--version' || cmd === '-v') {
|
|
24
|
+
const pkg = await import('../package.json', {
|
|
25
|
+
with: { type: 'json' },
|
|
26
|
+
});
|
|
27
|
+
process.stdout.write((pkg.default?.version ?? 'unknown') + '\n');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!cmd) {
|
|
31
|
+
const { pick } = await import('./commands/pick.js');
|
|
32
|
+
await pick();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (cmd === 'add') {
|
|
36
|
+
if (!rest[0]) {
|
|
37
|
+
process.stderr.write(`Usage: ${CLI_NAME} add <recipe-slug>\n`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
const { add } = await import('./commands/add.js');
|
|
41
|
+
await add(rest[0]);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (cmd === 'list') {
|
|
45
|
+
const { list } = await import('./commands/list.js');
|
|
46
|
+
await list();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (cmd === 'init') {
|
|
50
|
+
const { init } = await import('./commands/init.js');
|
|
51
|
+
await init();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
process.stderr.write(`Unknown command: ${cmd}\n\n${HELP}`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
main().catch((e) => {
|
|
58
|
+
process.stderr.write(red(e instanceof Error ? e.message : String(e)) + '\n');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAA;AAEnC,MAAM,IAAI,GAAG,GAAG,QAAQ;;;IAGpB,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;;;;CAIX,CAAA;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,CAAC,EAAE,AAAD,EAAG,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAA;IAEvC,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC1B,OAAM;IACR,CAAC;IAED,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,iBAAiB,EAAE;YAC1C,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;SACF,CAAC,CAAA;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,CAAE,GAA0C,CAAC,OAAO,EAAE,OAAO,IAAI,SAAS,CAAC,GAAG,IAAI,CACnF,CAAA;QACD,OAAM;IACR,CAAC;IAED,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAA;QACnD,MAAM,IAAI,EAAE,CAAA;QACZ,OAAM;IACR,CAAC;IAED,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,QAAQ,sBAAsB,CAAC,CAAA;YAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QACD,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAA;QACjD,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QAClB,OAAM;IACR,CAAC;IAED,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACnB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAA;QACnD,MAAM,IAAI,EAAE,CAAA;QACZ,OAAM;IACR,CAAC;IAED,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACnB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAA;QACnD,MAAM,IAAI,EAAE,CAAA;QACZ,OAAM;IACR,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,GAAG,OAAO,IAAI,EAAE,CAAC,CAAA;IAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { resolveRecipe, installPlan } from '@hanzogui/recipes';
|
|
2
|
+
import { green, gray, bold } from '../lib/ansi.js';
|
|
3
|
+
export async function add(slug) {
|
|
4
|
+
const plan = await resolveRecipe(slug);
|
|
5
|
+
const paths = await installPlan(plan);
|
|
6
|
+
process.stdout.write(green(`Installed "${plan.recipe.name}"`) + '\n');
|
|
7
|
+
if (plan.transitiveRecipes.length > 0) {
|
|
8
|
+
process.stdout.write(gray(`+ ${plan.transitiveRecipes.length} dependent recipe${plan.transitiveRecipes.length === 1 ? '' : 's'}: ${plan.transitiveRecipes.map((r) => r.slug).join(', ')}\n`));
|
|
9
|
+
}
|
|
10
|
+
for (const p of paths)
|
|
11
|
+
process.stdout.write(` ${p}\n`);
|
|
12
|
+
if (plan.recipe.npmDeps.length > 0) {
|
|
13
|
+
process.stdout.write('\n' + gray('Install these npm deps:') + '\n');
|
|
14
|
+
process.stdout.write(` ${bold('npm i ' + plan.recipe.npmDeps.join(' '))}\n`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAElD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAY;IACpC,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAA;IACtC,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAA;IAErC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;IACrE,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CACF,KAAK,IAAI,CAAC,iBAAiB,CAAC,MAAM,oBAChC,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAC7C,KAAK,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAC9D,CACF,CAAA;IACH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACvD,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,yBAAyB,CAAC,GAAG,IAAI,CAAC,CAAA;QACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAA;IAC/E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { existsSync, promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { findProjectRoot, DEFAULT_INSTALL_DIR } from '@hanzogui/recipes';
|
|
4
|
+
import { green, yellow } from '../lib/ansi.js';
|
|
5
|
+
export async function init() {
|
|
6
|
+
const root = await findProjectRoot();
|
|
7
|
+
const dest = path.join(root, 'gui.config.json');
|
|
8
|
+
if (existsSync(dest)) {
|
|
9
|
+
process.stdout.write(yellow(`gui.config.json already exists at ${dest}\n`));
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
await fs.writeFile(dest, JSON.stringify({ installDir: DEFAULT_INSTALL_DIR }, null, 2) + '\n');
|
|
13
|
+
process.stdout.write(green(`Wrote ${dest}\n`));
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAA;AACpD,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAE9C,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAA;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAA;IAC/C,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,qCAAqC,IAAI,IAAI,CAAC,CAAC,CAAA;QAC3E,OAAM;IACR,CAAC;IACD,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,EACJ,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,mBAAmB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CACpE,CAAA;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAA;AAChD,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { listRecipes } from '@hanzogui/recipes';
|
|
2
|
+
import { bold, cyan, gray, yellow } from '../lib/ansi.js';
|
|
3
|
+
export async function list() {
|
|
4
|
+
var _a;
|
|
5
|
+
const recipes = await listRecipes();
|
|
6
|
+
if (recipes.length === 0) {
|
|
7
|
+
process.stdout.write(yellow('No recipes published yet.\n'));
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const byCategory = {};
|
|
11
|
+
for (const r of recipes)
|
|
12
|
+
(byCategory[_a = r.category || 'misc'] || (byCategory[_a] = [])).push(r);
|
|
13
|
+
for (const [cat, items] of Object.entries(byCategory)) {
|
|
14
|
+
process.stdout.write(`\n${bold(cat)}\n`);
|
|
15
|
+
for (const r of items) {
|
|
16
|
+
process.stdout.write(` ${cyan(r.slug.padEnd(24))} ${gray(r.description)}\n`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
process.stdout.write('\n');
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAEzD,MAAM,CAAC,KAAK,UAAU,IAAI;;IACxB,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;IACnC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,CAAA;QAC3D,OAAM;IACR,CAAC;IACD,MAAM,UAAU,GAAmC,EAAE,CAAA;IACrD,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,CAAC,UAAU,MAAC,CAAC,CAAC,QAAQ,IAAI,MAAM,MAA/B,UAAU,OAA2B,EAAE,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1E,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACxC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QAChF,CAAC;IACH,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import Fuse from 'fuse.js';
|
|
2
|
+
import * as readline from 'node:readline/promises';
|
|
3
|
+
import { listRecipes } from '@hanzogui/recipes';
|
|
4
|
+
import { bold, cyan, dim, gray } from '../lib/ansi.js';
|
|
5
|
+
import { add } from './add.js';
|
|
6
|
+
export async function pick() {
|
|
7
|
+
const recipes = await listRecipes();
|
|
8
|
+
if (recipes.length === 0) {
|
|
9
|
+
process.stdout.write('No recipes published yet.\n');
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const fuse = new Fuse(recipes, {
|
|
13
|
+
keys: ['name', 'slug', 'category', 'description'],
|
|
14
|
+
threshold: 0.4,
|
|
15
|
+
});
|
|
16
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
17
|
+
try {
|
|
18
|
+
const query = (await rl.question(bold('Search recipes') + ' (empty = show all): ')).trim();
|
|
19
|
+
const hits = query ? fuse.search(query).map((h) => h.item) : recipes;
|
|
20
|
+
if (hits.length === 0) {
|
|
21
|
+
process.stdout.write(dim('No matches.\n'));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
process.stdout.write('\n');
|
|
25
|
+
hits.slice(0, 20).forEach((r, i) => {
|
|
26
|
+
process.stdout.write(` ${cyan(String(i + 1).padStart(2))} ${bold(r.name)} ${gray(r.slug)}\n`);
|
|
27
|
+
process.stdout.write(` ${gray(r.description)}\n`);
|
|
28
|
+
});
|
|
29
|
+
process.stdout.write('\n');
|
|
30
|
+
const pickRaw = (await rl.question('Pick a number (or paste a slug): ')).trim();
|
|
31
|
+
if (!pickRaw)
|
|
32
|
+
return;
|
|
33
|
+
let slug;
|
|
34
|
+
const asNum = Number.parseInt(pickRaw, 10);
|
|
35
|
+
if (!Number.isNaN(asNum) && asNum >= 1 && asNum <= hits.length) {
|
|
36
|
+
slug = hits[asNum - 1].slug;
|
|
37
|
+
}
|
|
38
|
+
else if (recipes.find((r) => r.slug === pickRaw)) {
|
|
39
|
+
slug = pickRaw;
|
|
40
|
+
}
|
|
41
|
+
if (!slug) {
|
|
42
|
+
process.stdout.write(dim(`No recipe matches "${pickRaw}".\n`));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
process.stdout.write('\n');
|
|
46
|
+
await add(slug);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
rl.close();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=pick.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pick.js","sourceRoot":"","sources":["../../../src/commands/pick.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,eAAe,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const ESC = '\x1b[';
|
|
2
|
+
const isTTY = process.stdout.isTTY === true;
|
|
3
|
+
const wrap = (open, close) => (s) => isTTY ? `${ESC}${open}m${s}${ESC}${close}m` : s;
|
|
4
|
+
export const bold = wrap(1, 22);
|
|
5
|
+
export const dim = wrap(2, 22);
|
|
6
|
+
export const red = wrap(31, 39);
|
|
7
|
+
export const green = wrap(32, 39);
|
|
8
|
+
export const yellow = wrap(33, 39);
|
|
9
|
+
export const cyan = wrap(36, 39);
|
|
10
|
+
export const gray = wrap(90, 39);
|
|
11
|
+
//# sourceMappingURL=ansi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ansi.js","sourceRoot":"","sources":["../../../src/lib/ansi.ts"],"names":[],"mappings":"AAAA,MAAM,GAAG,GAAG,OAAO,CAAA;AACnB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAA;AAC3C,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE,CAAC,CAAC,CAAS,EAAE,EAAE,CAC1D,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;AAEjD,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAC/B,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAC9B,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;AAC/B,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;AACjC,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;AAClC,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;AAChC,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,37 +1,43 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzogui/get",
|
|
3
|
-
"version": "8.3.
|
|
3
|
+
"version": "8.3.3",
|
|
4
4
|
"description": "CLI installer for Hanzo GUI recipes.",
|
|
5
|
+
"homepage": "https://gui.hanzo.ai",
|
|
5
6
|
"license": "BSD-3-Clause",
|
|
6
7
|
"author": "Hanzo AI <dev@hanzo.ai>",
|
|
7
|
-
"homepage": "https://gui.hanzo.ai",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/hanzoai/gui.git",
|
|
10
|
+
"url": "git+https://github.com/hanzoai/gui.git",
|
|
11
11
|
"directory": "pkgs/get"
|
|
12
12
|
},
|
|
13
13
|
"bin": {
|
|
14
|
-
"hanzo-gui-get": "./dist/cli.js"
|
|
14
|
+
"hanzo-gui-get": "./dist/esm/cli.js"
|
|
15
15
|
},
|
|
16
|
-
"type": "module",
|
|
17
|
-
"main": "./dist/cli.js",
|
|
18
16
|
"source": "src/cli.ts",
|
|
19
17
|
"files": [
|
|
20
|
-
"src
|
|
21
|
-
"
|
|
18
|
+
"src",
|
|
19
|
+
"types",
|
|
22
20
|
"dist"
|
|
23
21
|
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"exports": {
|
|
24
|
+
"./package.json": "./package.json"
|
|
25
|
+
},
|
|
24
26
|
"publishConfig": {
|
|
25
27
|
"access": "public"
|
|
26
28
|
},
|
|
27
29
|
"scripts": {
|
|
28
|
-
"build": "
|
|
29
|
-
"
|
|
30
|
-
"
|
|
30
|
+
"build": "hanzogui-build --skip-native",
|
|
31
|
+
"test": "bun test",
|
|
32
|
+
"clean": "hanzogui-build clean",
|
|
33
|
+
"clean:build": "hanzogui-build clean:build"
|
|
31
34
|
},
|
|
32
35
|
"dependencies": {
|
|
33
|
-
"@hanzogui/recipes": "8.3.
|
|
34
|
-
"fuse.js": "7.
|
|
36
|
+
"@hanzogui/recipes": "8.3.3",
|
|
37
|
+
"fuse.js": "^7.5.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@hanzogui/build": "8.3.3"
|
|
35
41
|
},
|
|
36
42
|
"engines": {
|
|
37
43
|
"node": ">=20"
|
package/src/cli.ts
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { test, expect, afterEach } from 'bun:test'
|
|
2
|
+
import { mkdtemp, readFile, writeFile, rm } from 'node:fs/promises'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import os from 'node:os'
|
|
5
|
+
import { init } from './init.js'
|
|
6
|
+
|
|
7
|
+
const created: string[] = []
|
|
8
|
+
afterEach(async () => {
|
|
9
|
+
for (const d of created.splice(0)) await rm(d, { recursive: true, force: true })
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
async function project(): Promise<string> {
|
|
13
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), 'guiget-init-'))
|
|
14
|
+
await writeFile(path.join(dir, 'package.json'), JSON.stringify({ workspaces: [] }))
|
|
15
|
+
created.push(dir)
|
|
16
|
+
return dir
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
test('init writes gui.config.json with default installDir', async () => {
|
|
20
|
+
const dir = await project()
|
|
21
|
+
const cwd = process.cwd()
|
|
22
|
+
process.chdir(dir)
|
|
23
|
+
try {
|
|
24
|
+
await init()
|
|
25
|
+
const written = JSON.parse(await readFile(path.join(dir, 'gui.config.json'), 'utf8'))
|
|
26
|
+
expect(written).toEqual({ installDir: 'src/gui' })
|
|
27
|
+
} finally {
|
|
28
|
+
process.chdir(cwd)
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
test('init is idempotent (no overwrite when file exists)', async () => {
|
|
33
|
+
const dir = await project()
|
|
34
|
+
const existing = JSON.stringify({ installDir: 'src/widgets' })
|
|
35
|
+
await writeFile(path.join(dir, 'gui.config.json'), existing)
|
|
36
|
+
const cwd = process.cwd()
|
|
37
|
+
process.chdir(dir)
|
|
38
|
+
try {
|
|
39
|
+
await init()
|
|
40
|
+
expect(await readFile(path.join(dir, 'gui.config.json'), 'utf8')).toBe(existing)
|
|
41
|
+
} finally {
|
|
42
|
+
process.chdir(cwd)
|
|
43
|
+
}
|
|
44
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { test, expect } from 'bun:test'
|
|
2
|
+
import { bold, red, green, gray } from './ansi.js'
|
|
3
|
+
|
|
4
|
+
test('color helpers return wrapped strings on TTY, plain otherwise', () => {
|
|
5
|
+
// In the test runner stdout typically isn't a TTY, so we get pass-through.
|
|
6
|
+
// The contract: result is always a string that contains the input substring.
|
|
7
|
+
for (const fn of [bold, red, green, gray]) {
|
|
8
|
+
const out = fn('hello')
|
|
9
|
+
expect(typeof out).toBe('string')
|
|
10
|
+
expect(out.includes('hello')).toBe(true)
|
|
11
|
+
}
|
|
12
|
+
})
|
package/types/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAGA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBrD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAKA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAY1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAGA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAe1C"}
|