@hypercli/gen 0.1.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/LICENSE +21 -0
- package/README.md +24 -0
- package/dist/actions/communication.d.ts +201 -0
- package/dist/actions/communication.d.ts.map +1 -0
- package/dist/actions/communication.js +515 -0
- package/dist/actions/communication.js.map +1 -0
- package/dist/actions/decorator.d.ts +22 -0
- package/dist/actions/decorator.d.ts.map +1 -0
- package/dist/actions/decorator.js +110 -0
- package/dist/actions/decorator.js.map +1 -0
- package/dist/actions/executor.d.ts +85 -0
- package/dist/actions/executor.d.ts.map +1 -0
- package/dist/actions/executor.js +289 -0
- package/dist/actions/executor.js.map +1 -0
- package/dist/actions/index.d.ts +14 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +15 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/actions/parameter-resolver.d.ts +54 -0
- package/dist/actions/parameter-resolver.d.ts.map +1 -0
- package/dist/actions/parameter-resolver.js +300 -0
- package/dist/actions/parameter-resolver.js.map +1 -0
- package/dist/actions/registry.d.ts +78 -0
- package/dist/actions/registry.d.ts.map +1 -0
- package/dist/actions/registry.js +221 -0
- package/dist/actions/registry.js.map +1 -0
- package/dist/actions/types.d.ts +109 -0
- package/dist/actions/types.d.ts.map +1 -0
- package/dist/actions/types.js +31 -0
- package/dist/actions/types.js.map +1 -0
- package/dist/actions/utils.d.ts +42 -0
- package/dist/actions/utils.d.ts.map +1 -0
- package/dist/actions/utils.js +144 -0
- package/dist/actions/utils.js.map +1 -0
- package/dist/ai/ai-collector.d.ts +52 -0
- package/dist/ai/ai-collector.d.ts.map +1 -0
- package/dist/ai/ai-collector.js +64 -0
- package/dist/ai/ai-collector.js.map +1 -0
- package/dist/ai/ai-config.d.ts +230 -0
- package/dist/ai/ai-config.d.ts.map +1 -0
- package/dist/ai/ai-config.js +8 -0
- package/dist/ai/ai-config.js.map +1 -0
- package/dist/ai/ai-service.d.ts +66 -0
- package/dist/ai/ai-service.d.ts.map +1 -0
- package/dist/ai/ai-service.js +198 -0
- package/dist/ai/ai-service.js.map +1 -0
- package/dist/ai/ai-variable-resolver.d.ts +59 -0
- package/dist/ai/ai-variable-resolver.d.ts.map +1 -0
- package/dist/ai/ai-variable-resolver.js +219 -0
- package/dist/ai/ai-variable-resolver.js.map +1 -0
- package/dist/ai/context-collector.d.ts +30 -0
- package/dist/ai/context-collector.d.ts.map +1 -0
- package/dist/ai/context-collector.js +158 -0
- package/dist/ai/context-collector.js.map +1 -0
- package/dist/ai/cost-tracker.d.ts +41 -0
- package/dist/ai/cost-tracker.d.ts.map +1 -0
- package/dist/ai/cost-tracker.js +131 -0
- package/dist/ai/cost-tracker.js.map +1 -0
- package/dist/ai/env.d.ts +36 -0
- package/dist/ai/env.d.ts.map +1 -0
- package/dist/ai/env.js +100 -0
- package/dist/ai/env.js.map +1 -0
- package/dist/ai/index.d.ts +17 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +25 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/model-router.d.ts +32 -0
- package/dist/ai/model-router.d.ts.map +1 -0
- package/dist/ai/model-router.js +113 -0
- package/dist/ai/model-router.js.map +1 -0
- package/dist/ai/output-validator.d.ts +24 -0
- package/dist/ai/output-validator.d.ts.map +1 -0
- package/dist/ai/output-validator.js +279 -0
- package/dist/ai/output-validator.js.map +1 -0
- package/dist/ai/prompt-assembler.d.ts +30 -0
- package/dist/ai/prompt-assembler.d.ts.map +1 -0
- package/dist/ai/prompt-assembler.js +93 -0
- package/dist/ai/prompt-assembler.js.map +1 -0
- package/dist/ai/prompt-pipeline.d.ts +63 -0
- package/dist/ai/prompt-pipeline.d.ts.map +1 -0
- package/dist/ai/prompt-pipeline.js +119 -0
- package/dist/ai/prompt-pipeline.js.map +1 -0
- package/dist/ai/prompt-template.jig +88 -0
- package/dist/ai/transports/api-transport.d.ts +12 -0
- package/dist/ai/transports/api-transport.d.ts.map +1 -0
- package/dist/ai/transports/api-transport.js +86 -0
- package/dist/ai/transports/api-transport.js.map +1 -0
- package/dist/ai/transports/command-transport.d.ts +20 -0
- package/dist/ai/transports/command-transport.d.ts.map +1 -0
- package/dist/ai/transports/command-transport.js +203 -0
- package/dist/ai/transports/command-transport.js.map +1 -0
- package/dist/ai/transports/index.d.ts +11 -0
- package/dist/ai/transports/index.d.ts.map +1 -0
- package/dist/ai/transports/index.js +10 -0
- package/dist/ai/transports/index.js.map +1 -0
- package/dist/ai/transports/resolve-transport.d.ts +15 -0
- package/dist/ai/transports/resolve-transport.d.ts.map +1 -0
- package/dist/ai/transports/resolve-transport.js +96 -0
- package/dist/ai/transports/resolve-transport.js.map +1 -0
- package/dist/ai/transports/stdout-transport.d.ts +14 -0
- package/dist/ai/transports/stdout-transport.d.ts.map +1 -0
- package/dist/ai/transports/stdout-transport.js +27 -0
- package/dist/ai/transports/stdout-transport.js.map +1 -0
- package/dist/ai/transports/types.d.ts +77 -0
- package/dist/ai/transports/types.d.ts.map +1 -0
- package/dist/ai/transports/types.js +8 -0
- package/dist/ai/transports/types.js.map +1 -0
- package/dist/commands/cookbook/info.d.ts +22 -0
- package/dist/commands/cookbook/info.d.ts.map +1 -0
- package/dist/commands/cookbook/info.js +217 -0
- package/dist/commands/cookbook/info.js.map +1 -0
- package/dist/commands/cookbook/list.d.ts +20 -0
- package/dist/commands/cookbook/list.d.ts.map +1 -0
- package/dist/commands/cookbook/list.js +133 -0
- package/dist/commands/cookbook/list.js.map +1 -0
- package/dist/commands/gen.d.ts +65 -0
- package/dist/commands/gen.d.ts.map +1 -0
- package/dist/commands/gen.js +478 -0
- package/dist/commands/gen.js.map +1 -0
- package/dist/commands/recipe/info.d.ts +18 -0
- package/dist/commands/recipe/info.d.ts.map +1 -0
- package/dist/commands/recipe/info.js +89 -0
- package/dist/commands/recipe/info.js.map +1 -0
- package/dist/commands/recipe/list.d.ts +29 -0
- package/dist/commands/recipe/list.d.ts.map +1 -0
- package/dist/commands/recipe/list.js +215 -0
- package/dist/commands/recipe/list.js.map +1 -0
- package/dist/commands/recipe/run.d.ts +44 -0
- package/dist/commands/recipe/run.d.ts.map +1 -0
- package/dist/commands/recipe/run.js +239 -0
- package/dist/commands/recipe/run.js.map +1 -0
- package/dist/commands/recipe/validate.d.ts +19 -0
- package/dist/commands/recipe/validate.d.ts.map +1 -0
- package/dist/commands/recipe/validate.js +66 -0
- package/dist/commands/recipe/validate.js.map +1 -0
- package/dist/discovery/generator-discovery.d.ts +130 -0
- package/dist/discovery/generator-discovery.d.ts.map +1 -0
- package/dist/discovery/generator-discovery.js +674 -0
- package/dist/discovery/generator-discovery.js.map +1 -0
- package/dist/discovery/index.d.ts +8 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +7 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/hooks/command-not-found.d.ts +18 -0
- package/dist/hooks/command-not-found.d.ts.map +1 -0
- package/dist/hooks/command-not-found.js +182 -0
- package/dist/hooks/command-not-found.js.map +1 -0
- package/dist/hooks/suggest.d.ts +13 -0
- package/dist/hooks/suggest.d.ts.map +1 -0
- package/dist/hooks/suggest.js +28 -0
- package/dist/hooks/suggest.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/base-command.d.ts +26 -0
- package/dist/lib/base-command.d.ts.map +1 -0
- package/dist/lib/base-command.js +24 -0
- package/dist/lib/base-command.js.map +1 -0
- package/dist/lib/flags.d.ts +33 -0
- package/dist/lib/flags.d.ts.map +1 -0
- package/dist/lib/flags.js +64 -0
- package/dist/lib/flags.js.map +1 -0
- package/dist/ops/add.d.ts +4 -0
- package/dist/ops/add.d.ts.map +1 -0
- package/dist/ops/add.js +85 -0
- package/dist/ops/add.js.map +1 -0
- package/dist/ops/inject.d.ts +4 -0
- package/dist/ops/inject.d.ts.map +1 -0
- package/dist/ops/inject.js +28 -0
- package/dist/ops/inject.js.map +1 -0
- package/dist/ops/injector.d.ts +4 -0
- package/dist/ops/injector.d.ts.map +1 -0
- package/dist/ops/injector.js +68 -0
- package/dist/ops/injector.js.map +1 -0
- package/dist/ops/result.d.ts +3 -0
- package/dist/ops/result.d.ts.map +1 -0
- package/dist/ops/result.js +8 -0
- package/dist/ops/result.js.map +1 -0
- package/dist/prompts/interactive-prompts.d.ts +152 -0
- package/dist/prompts/interactive-prompts.d.ts.map +1 -0
- package/dist/prompts/interactive-prompts.js +574 -0
- package/dist/prompts/interactive-prompts.js.map +1 -0
- package/dist/recipe-engine/group-executor.d.ts +97 -0
- package/dist/recipe-engine/group-executor.d.ts.map +1 -0
- package/dist/recipe-engine/group-executor.js +293 -0
- package/dist/recipe-engine/group-executor.js.map +1 -0
- package/dist/recipe-engine/index.d.ts +112 -0
- package/dist/recipe-engine/index.d.ts.map +1 -0
- package/dist/recipe-engine/index.js +223 -0
- package/dist/recipe-engine/index.js.map +1 -0
- package/dist/recipe-engine/output-evaluator.d.ts +28 -0
- package/dist/recipe-engine/output-evaluator.d.ts.map +1 -0
- package/dist/recipe-engine/output-evaluator.js +78 -0
- package/dist/recipe-engine/output-evaluator.js.map +1 -0
- package/dist/recipe-engine/recipe-engine.d.ts +227 -0
- package/dist/recipe-engine/recipe-engine.d.ts.map +1 -0
- package/dist/recipe-engine/recipe-engine.js +1036 -0
- package/dist/recipe-engine/recipe-engine.js.map +1 -0
- package/dist/recipe-engine/step-executor.d.ts +172 -0
- package/dist/recipe-engine/step-executor.d.ts.map +1 -0
- package/dist/recipe-engine/step-executor.js +802 -0
- package/dist/recipe-engine/step-executor.js.map +1 -0
- package/dist/recipe-engine/tools/action-tool.d.ts +103 -0
- package/dist/recipe-engine/tools/action-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/action-tool.js +473 -0
- package/dist/recipe-engine/tools/action-tool.js.map +1 -0
- package/dist/recipe-engine/tools/ai-tool.d.ts +26 -0
- package/dist/recipe-engine/tools/ai-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/ai-tool.js +233 -0
- package/dist/recipe-engine/tools/ai-tool.js.map +1 -0
- package/dist/recipe-engine/tools/base.d.ts +214 -0
- package/dist/recipe-engine/tools/base.d.ts.map +1 -0
- package/dist/recipe-engine/tools/base.js +397 -0
- package/dist/recipe-engine/tools/base.js.map +1 -0
- package/dist/recipe-engine/tools/codemod-tool.d.ts +130 -0
- package/dist/recipe-engine/tools/codemod-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/codemod-tool.js +786 -0
- package/dist/recipe-engine/tools/codemod-tool.js.map +1 -0
- package/dist/recipe-engine/tools/ensure-dirs-tool.d.ts +21 -0
- package/dist/recipe-engine/tools/ensure-dirs-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/ensure-dirs-tool.js +130 -0
- package/dist/recipe-engine/tools/ensure-dirs-tool.js.map +1 -0
- package/dist/recipe-engine/tools/index.d.ts +126 -0
- package/dist/recipe-engine/tools/index.d.ts.map +1 -0
- package/dist/recipe-engine/tools/index.js +290 -0
- package/dist/recipe-engine/tools/index.js.map +1 -0
- package/dist/recipe-engine/tools/install-tool.d.ts +20 -0
- package/dist/recipe-engine/tools/install-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/install-tool.js +194 -0
- package/dist/recipe-engine/tools/install-tool.js.map +1 -0
- package/dist/recipe-engine/tools/parallel-tool.d.ts +21 -0
- package/dist/recipe-engine/tools/parallel-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/parallel-tool.js +134 -0
- package/dist/recipe-engine/tools/parallel-tool.js.map +1 -0
- package/dist/recipe-engine/tools/patch-tool.d.ts +21 -0
- package/dist/recipe-engine/tools/patch-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/patch-tool.js +248 -0
- package/dist/recipe-engine/tools/patch-tool.js.map +1 -0
- package/dist/recipe-engine/tools/prompt-tool.d.ts +25 -0
- package/dist/recipe-engine/tools/prompt-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/prompt-tool.js +162 -0
- package/dist/recipe-engine/tools/prompt-tool.js.map +1 -0
- package/dist/recipe-engine/tools/query-tool.d.ts +21 -0
- package/dist/recipe-engine/tools/query-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/query-tool.js +249 -0
- package/dist/recipe-engine/tools/query-tool.js.map +1 -0
- package/dist/recipe-engine/tools/recipe-tool.d.ts +103 -0
- package/dist/recipe-engine/tools/recipe-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/recipe-tool.js +617 -0
- package/dist/recipe-engine/tools/recipe-tool.js.map +1 -0
- package/dist/recipe-engine/tools/registry.d.ts +151 -0
- package/dist/recipe-engine/tools/registry.d.ts.map +1 -0
- package/dist/recipe-engine/tools/registry.js +244 -0
- package/dist/recipe-engine/tools/registry.js.map +1 -0
- package/dist/recipe-engine/tools/sequence-tool.d.ts +22 -0
- package/dist/recipe-engine/tools/sequence-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/sequence-tool.js +122 -0
- package/dist/recipe-engine/tools/sequence-tool.js.map +1 -0
- package/dist/recipe-engine/tools/shell-tool.d.ts +25 -0
- package/dist/recipe-engine/tools/shell-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/shell-tool.js +149 -0
- package/dist/recipe-engine/tools/shell-tool.js.map +1 -0
- package/dist/recipe-engine/tools/template-tool.d.ts +88 -0
- package/dist/recipe-engine/tools/template-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/template-tool.js +613 -0
- package/dist/recipe-engine/tools/template-tool.js.map +1 -0
- package/dist/recipe-engine/types.d.ts +963 -0
- package/dist/recipe-engine/types.d.ts.map +1 -0
- package/dist/recipe-engine/types.js +94 -0
- package/dist/recipe-engine/types.js.map +1 -0
- package/dist/template-engines/ai-tags.d.ts +26 -0
- package/dist/template-engines/ai-tags.d.ts.map +1 -0
- package/dist/template-engines/ai-tags.js +233 -0
- package/dist/template-engines/ai-tags.js.map +1 -0
- package/dist/template-engines/index.d.ts +8 -0
- package/dist/template-engines/index.d.ts.map +1 -0
- package/dist/template-engines/index.js +8 -0
- package/dist/template-engines/index.js.map +1 -0
- package/dist/template-engines/jig-engine.d.ts +47 -0
- package/dist/template-engines/jig-engine.d.ts.map +1 -0
- package/dist/template-engines/jig-engine.js +173 -0
- package/dist/template-engines/jig-engine.js.map +1 -0
- package/dist/utils/coerce-value.d.ts +7 -0
- package/dist/utils/coerce-value.d.ts.map +1 -0
- package/dist/utils/coerce-value.js +18 -0
- package/dist/utils/coerce-value.js.map +1 -0
- package/dist/utils/diff.d.ts +8 -0
- package/dist/utils/diff.d.ts.map +1 -0
- package/dist/utils/diff.js +10 -0
- package/dist/utils/diff.js.map +1 -0
- package/dist/utils/global-packages.d.ts +11 -0
- package/dist/utils/global-packages.d.ts.map +1 -0
- package/dist/utils/global-packages.js +88 -0
- package/dist/utils/global-packages.js.map +1 -0
- package/dist/utils/pager.d.ts +6 -0
- package/dist/utils/pager.d.ts.map +1 -0
- package/dist/utils/pager.js +41 -0
- package/dist/utils/pager.js.map +1 -0
- package/help/cookbook/info.md +35 -0
- package/help/cookbook/list.md +37 -0
- package/help/gen.md +26 -0
- package/help/recipe/run.md +52 -0
- package/help/recipe/validate.md +51 -0
- package/oclif.manifest.json +580 -0
- package/package.json +120 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jig Template Engine
|
|
3
|
+
*
|
|
4
|
+
* Singleton module wrapping @jig-lang/jig (forked from Edge.js).
|
|
5
|
+
* Jig is purpose-built for code generation: no HTML escaping,
|
|
6
|
+
* automatic indentation management, full JS expressions in templates,
|
|
7
|
+
* and `{{ filter :: value }}` syntax.
|
|
8
|
+
*/
|
|
9
|
+
import { helpers } from "@hypercli/core";
|
|
10
|
+
import { Edge } from "@jig-lang/jig";
|
|
11
|
+
import createDebug from "debug";
|
|
12
|
+
import { AiCollector } from "#ai/ai-collector";
|
|
13
|
+
import { registerAiTags } from "./ai-tags.js";
|
|
14
|
+
const debug = createDebug("hypergen:template:jig");
|
|
15
|
+
let jig = null;
|
|
16
|
+
/**
|
|
17
|
+
* Track registered globals for collision warnings.
|
|
18
|
+
* Maps global name -> source string (e.g. "kit:@kit/nextjs").
|
|
19
|
+
*/
|
|
20
|
+
const registeredGlobals = new Map();
|
|
21
|
+
/**
|
|
22
|
+
* Get the Jig (Edge) instance, creating it if needed.
|
|
23
|
+
*/
|
|
24
|
+
export function getJig() {
|
|
25
|
+
if (!jig) {
|
|
26
|
+
initializeJig();
|
|
27
|
+
}
|
|
28
|
+
return jig;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Initialize (or reinitialize) the Jig template engine.
|
|
32
|
+
*/
|
|
33
|
+
export function initializeJig(config) {
|
|
34
|
+
jig = Edge.create({ cache: config?.cache ?? false });
|
|
35
|
+
registeredGlobals.clear();
|
|
36
|
+
registerFilters(jig);
|
|
37
|
+
registerAi2PassTags(jig);
|
|
38
|
+
debug("Jig template engine initialized (cache=%s)", config?.cache ?? false);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Render a template string with the given context.
|
|
42
|
+
*/
|
|
43
|
+
export async function renderTemplate(template, context) {
|
|
44
|
+
const engine = getJig();
|
|
45
|
+
try {
|
|
46
|
+
return await engine.renderRaw(template, context);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
throw new Error(`Jig template rendering failed: ${error.message}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Render a template string synchronously.
|
|
54
|
+
*/
|
|
55
|
+
export function renderTemplateSync(template, context) {
|
|
56
|
+
const engine = getJig();
|
|
57
|
+
try {
|
|
58
|
+
return engine.renderRawSync(template, context);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new Error(`Jig template rendering failed: ${error.message}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Render a template file with the given context.
|
|
66
|
+
* The templateName is resolved against mounted disk paths.
|
|
67
|
+
*/
|
|
68
|
+
export async function renderFile(templateName, context) {
|
|
69
|
+
const engine = getJig();
|
|
70
|
+
try {
|
|
71
|
+
return await engine.render(templateName, context);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
throw new Error(`Jig file rendering failed (${templateName}): ${error.message}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Mount a directory so Jig can resolve template files from it.
|
|
79
|
+
*/
|
|
80
|
+
export function mountDirectory(dirPath, diskName) {
|
|
81
|
+
const engine = getJig();
|
|
82
|
+
if (diskName) {
|
|
83
|
+
engine.mount(diskName, dirPath);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
engine.mount(dirPath);
|
|
87
|
+
}
|
|
88
|
+
debug("Mounted directory: %s%s", dirPath, diskName ? ` as "${diskName}"` : "");
|
|
89
|
+
}
|
|
90
|
+
// ─── Filter Registration ──────────────────────────────────────────────
|
|
91
|
+
function registerFilters(edge) {
|
|
92
|
+
const { changeCase, inflection } = helpers;
|
|
93
|
+
// Case filters — use the change-case library for correctness
|
|
94
|
+
const caseFilters = {
|
|
95
|
+
camelCase: (v) => changeCase.camelCase(v),
|
|
96
|
+
pascalCase: (v) => changeCase.pascalCase(v),
|
|
97
|
+
snakeCase: (v) => changeCase.snakeCase(v),
|
|
98
|
+
kebabCase: (v) => changeCase.paramCase(v),
|
|
99
|
+
constantCase: (v) => changeCase.constantCase(v),
|
|
100
|
+
dotCase: (v) => changeCase.dotCase(v),
|
|
101
|
+
pathCase: (v) => changeCase.pathCase(v),
|
|
102
|
+
paramCase: (v) => changeCase.paramCase(v),
|
|
103
|
+
};
|
|
104
|
+
// Inflection filters
|
|
105
|
+
const inflectionFilters = {
|
|
106
|
+
pluralize: (v) => inflection.pluralize(v),
|
|
107
|
+
singularize: (v) => inflection.singularize(v),
|
|
108
|
+
};
|
|
109
|
+
// String filters
|
|
110
|
+
const stringFilters = {
|
|
111
|
+
capitalize: (v) => helpers.capitalize(v),
|
|
112
|
+
titleize: (v) => inflection.titleize(v),
|
|
113
|
+
humanize: (v) => inflection.humanize(v),
|
|
114
|
+
};
|
|
115
|
+
const allFilters = { ...caseFilters, ...inflectionFilters, ...stringFilters };
|
|
116
|
+
for (const [name, fn] of Object.entries(allFilters)) {
|
|
117
|
+
// Register as filter: {{ name :: camelCase }}
|
|
118
|
+
edge.registerFilter(name, (input) => fn(String(input)));
|
|
119
|
+
// Register as global so {{ camelCase(name) }} also works
|
|
120
|
+
edge.global(name, (input) => fn(String(input)));
|
|
121
|
+
}
|
|
122
|
+
debug("Registered %d filters + globals", Object.keys(allFilters).length);
|
|
123
|
+
}
|
|
124
|
+
// ─── Helper Registration ──────────────────────────────────────────────
|
|
125
|
+
/**
|
|
126
|
+
* Register helper functions as Jig globals.
|
|
127
|
+
* Warns on collision (last registration wins).
|
|
128
|
+
*
|
|
129
|
+
* @param helpers Record of name -> function
|
|
130
|
+
* @param source Human-readable source identifier for collision warnings
|
|
131
|
+
*/
|
|
132
|
+
export function registerHelpers(helpers, source) {
|
|
133
|
+
const engine = getJig();
|
|
134
|
+
for (const [name, value] of Object.entries(helpers)) {
|
|
135
|
+
if (typeof value === "function") {
|
|
136
|
+
if (registeredGlobals.has(name)) {
|
|
137
|
+
const existingSource = registeredGlobals.get(name);
|
|
138
|
+
console.warn(`Warning: Helper "${name}" from ${source ?? "unknown"} overwrites existing helper from ${existingSource}`);
|
|
139
|
+
}
|
|
140
|
+
engine.global(name, value);
|
|
141
|
+
registeredGlobals.set(name, source ?? "unknown");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
debug("Registered %d helpers from %s", Object.keys(helpers).length, source ?? "unknown");
|
|
145
|
+
}
|
|
146
|
+
// ─── AI Tags (2-Pass System) ──────────────────────────────────────────
|
|
147
|
+
function registerAi2PassTags(edge) {
|
|
148
|
+
try {
|
|
149
|
+
// Register @ai, @context, @prompt, @output tags
|
|
150
|
+
registerAiTags(edge);
|
|
151
|
+
// Register global runtime helpers that compiled tag code calls
|
|
152
|
+
const collector = AiCollector.getInstance();
|
|
153
|
+
edge.global("__hypergenAiCollect", (key, contexts, prompt, outputDesc, typeHint, examples, sourceFile) => {
|
|
154
|
+
collector.addEntry({
|
|
155
|
+
key,
|
|
156
|
+
contexts: contexts.filter((c) => c.trim()),
|
|
157
|
+
prompt: prompt.trim(),
|
|
158
|
+
outputDescription: outputDesc.trim(),
|
|
159
|
+
typeHint: typeHint || "",
|
|
160
|
+
examples: (examples || []).filter((e) => e.trim()).map((e) => e.trim()),
|
|
161
|
+
sourceFile: sourceFile || "unknown",
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
edge.global("__hypergenAddGlobalContext", (text) => {
|
|
165
|
+
collector.addGlobalContext(text);
|
|
166
|
+
});
|
|
167
|
+
debug("AI 2-pass tags registered");
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
debug("@ai 2-pass tag registration failed: %s", err instanceof Error ? err.message : String(err));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=jig-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jig-engine.js","sourceRoot":"","sources":["../../src/template-engines/jig-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coerce a CLI string value to its most likely native type.
|
|
3
|
+
* Converts boolean-like strings (true/false/yes/no/1/0) to booleans
|
|
4
|
+
* and numeric strings to numbers.
|
|
5
|
+
*/
|
|
6
|
+
export declare function coerceValue(value: string): unknown;
|
|
7
|
+
//# sourceMappingURL=coerce-value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coerce-value.d.ts","sourceRoot":"","sources":["../../src/utils/coerce-value.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAQlD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const BOOLEAN_TRUE = new Set(["true", "1", "yes"]);
|
|
2
|
+
const BOOLEAN_FALSE = new Set(["false", "0", "no"]);
|
|
3
|
+
/**
|
|
4
|
+
* Coerce a CLI string value to its most likely native type.
|
|
5
|
+
* Converts boolean-like strings (true/false/yes/no/1/0) to booleans
|
|
6
|
+
* and numeric strings to numbers.
|
|
7
|
+
*/
|
|
8
|
+
export function coerceValue(value) {
|
|
9
|
+
const lower = value.toLowerCase();
|
|
10
|
+
if (BOOLEAN_TRUE.has(lower))
|
|
11
|
+
return true;
|
|
12
|
+
if (BOOLEAN_FALSE.has(lower))
|
|
13
|
+
return false;
|
|
14
|
+
if (value !== "" && !Number.isNaN(Number(value)))
|
|
15
|
+
return Number(value);
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=coerce-value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coerce-value.js","sourceRoot":"","sources":["../../src/utils/coerce-value.ts"],"names":[],"mappings":"AAAA,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AACnD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AAEpD;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE3C,IAAI,KAAK,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAEvE,OAAO,KAAK,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/utils/diff.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,UAAU,CACzB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,MAAM,CAIR"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import disparity from "disparity";
|
|
2
|
+
/**
|
|
3
|
+
* Generate a colored unified diff between two strings.
|
|
4
|
+
*/
|
|
5
|
+
export function formatDiff(oldContent, newContent, options) {
|
|
6
|
+
return disparity.unified(oldContent, newContent, {
|
|
7
|
+
paths: [options?.oldLabel ?? "existing", options?.newLabel ?? "incoming"],
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/utils/diff.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC;;GAEG;AACH,MAAM,UAAU,UAAU,CACzB,UAAkB,EAClB,UAAkB,EAClB,OAAkD;IAElD,OAAO,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE;QAChD,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,OAAO,EAAE,QAAQ,IAAI,UAAU,CAAC;KACzE,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface GlobalPackage {
|
|
2
|
+
name: string;
|
|
3
|
+
path: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Get list of globally installed packages using the current engine's package manager.
|
|
7
|
+
* - If running in Bun, queries `bun pm ls -g`
|
|
8
|
+
* - Otherwise (Node), queries `npm list -g`
|
|
9
|
+
*/
|
|
10
|
+
export declare function getGlobalPackages(): Promise<GlobalPackage[]>;
|
|
11
|
+
//# sourceMappingURL=global-packages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-packages.d.ts","sourceRoot":"","sources":["../../src/utils/global-packages.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAOlE"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { exec } from "node:child_process";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
import createDebug from "debug";
|
|
5
|
+
const debug = createDebug("hypergen:utils:global-packages");
|
|
6
|
+
const execAsync = promisify(exec);
|
|
7
|
+
/**
|
|
8
|
+
* Get list of globally installed packages using the current engine's package manager.
|
|
9
|
+
* - If running in Bun, queries `bun pm ls -g`
|
|
10
|
+
* - Otherwise (Node), queries `npm list -g`
|
|
11
|
+
*/
|
|
12
|
+
export async function getGlobalPackages() {
|
|
13
|
+
const isBun = !!process.versions.bun;
|
|
14
|
+
if (isBun) {
|
|
15
|
+
return getBunGlobalPackages();
|
|
16
|
+
}
|
|
17
|
+
return getNpmGlobalPackages();
|
|
18
|
+
}
|
|
19
|
+
async function getNpmGlobalPackages() {
|
|
20
|
+
try {
|
|
21
|
+
// Get the global root first, as npm list json doesn't always include full paths for top level
|
|
22
|
+
const { stdout: rootStdout } = await execAsync("npm root -g");
|
|
23
|
+
const globalRoot = rootStdout.trim();
|
|
24
|
+
// Get the list in JSON format
|
|
25
|
+
const { stdout: listStdout } = await execAsync("npm list -g --depth=0 --json");
|
|
26
|
+
const list = JSON.parse(listStdout);
|
|
27
|
+
if (!list.dependencies)
|
|
28
|
+
return [];
|
|
29
|
+
return Object.keys(list.dependencies).map((name) => ({
|
|
30
|
+
name,
|
|
31
|
+
path: path.join(globalRoot, name),
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
debug("Failed to get npm global packages: %s", error);
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function getBunGlobalPackages() {
|
|
40
|
+
try {
|
|
41
|
+
// Bun doesn't output JSON for ls yet, need to parse text
|
|
42
|
+
// Output format:
|
|
43
|
+
// /path/to/global/install node_modules (count)
|
|
44
|
+
// ├── package@version
|
|
45
|
+
// └── package@version
|
|
46
|
+
const { stdout } = await execAsync("bun pm ls -g");
|
|
47
|
+
const lines = stdout.split("\n");
|
|
48
|
+
if (lines.length === 0)
|
|
49
|
+
return [];
|
|
50
|
+
// First line contains the root.
|
|
51
|
+
// Example: "/Users/user/.cache/.bun/install/global node_modules (1478)"
|
|
52
|
+
// We want the path part before " node_modules".
|
|
53
|
+
const firstLine = lines[0];
|
|
54
|
+
// Split by " node_modules" -> ["/Users/.../global", " (1478)"]
|
|
55
|
+
const rootPathPart = firstLine.split(" node_modules")[0];
|
|
56
|
+
// Based on `bun pm bin -g` vs `ls` observation, the packages are inside `node_modules` in that root
|
|
57
|
+
const globalRoot = path.join(rootPathPart.trim(), "node_modules");
|
|
58
|
+
const packages = [];
|
|
59
|
+
// Parse subsequent lines
|
|
60
|
+
for (let i = 1; i < lines.length; i++) {
|
|
61
|
+
const line = lines[i].trim();
|
|
62
|
+
if (!line)
|
|
63
|
+
continue;
|
|
64
|
+
// Lines start with ├── or └── depending on position
|
|
65
|
+
// remove tree characters
|
|
66
|
+
const cleanLine = line.replace(/^[└├]──\s*/, "");
|
|
67
|
+
// Format: name@version OR @scope/name@version
|
|
68
|
+
// We need to split name and version. Last @ is version separator.
|
|
69
|
+
const lastAtIndex = cleanLine.lastIndexOf("@");
|
|
70
|
+
if (lastAtIndex === -1)
|
|
71
|
+
continue; // Should not happen for valid output
|
|
72
|
+
const name = cleanLine.substring(0, lastAtIndex);
|
|
73
|
+
// Basic validation to avoid junk
|
|
74
|
+
if (name) {
|
|
75
|
+
packages.push({
|
|
76
|
+
name,
|
|
77
|
+
path: path.join(globalRoot, name),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return packages;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
debug("Failed to get bun global packages: %s", error);
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=global-packages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-packages.js","sourceRoot":"","sources":["../../src/utils/global-packages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pager.d.ts","sourceRoot":"","sources":["../../src/utils/pager.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC1D"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { unlinkSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
/**
|
|
6
|
+
* Display content in an interactive pager (less).
|
|
7
|
+
* Falls back to printing to stdout if less is not available.
|
|
8
|
+
*/
|
|
9
|
+
export function showInPager(content) {
|
|
10
|
+
const tmpFile = join(tmpdir(), `hyper-diff-${Date.now()}.txt`);
|
|
11
|
+
writeFileSync(tmpFile, content);
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
// -R: interpret ANSI colors
|
|
14
|
+
// -X: don't clear screen on exit
|
|
15
|
+
// -K: allow Ctrl-C to exit
|
|
16
|
+
const child = spawn("less", ["-RXK", tmpFile], {
|
|
17
|
+
stdio: "inherit",
|
|
18
|
+
env: {
|
|
19
|
+
...process.env,
|
|
20
|
+
LESS: "-RXK",
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
child.on("close", () => {
|
|
24
|
+
try {
|
|
25
|
+
unlinkSync(tmpFile);
|
|
26
|
+
}
|
|
27
|
+
catch { }
|
|
28
|
+
resolve();
|
|
29
|
+
});
|
|
30
|
+
child.on("error", () => {
|
|
31
|
+
// less not available — print to stdout
|
|
32
|
+
try {
|
|
33
|
+
unlinkSync(tmpFile);
|
|
34
|
+
}
|
|
35
|
+
catch { }
|
|
36
|
+
process.stdout.write(`${content}\n`);
|
|
37
|
+
resolve();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=pager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pager.js","sourceRoot":"","sources":["../../src/utils/pager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC/D,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAEhC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,4BAA4B;QAC5B,iCAAiC;QACjC,2BAA2B;QAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;YAC9C,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE;gBACJ,GAAG,OAAO,CAAC,GAAG;gBACd,IAAI,EAAE,MAAM;aACZ;SACD,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACtB,IAAI,CAAC;gBACJ,UAAU,CAAC,OAAO,CAAC,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,OAAO,EAAE,CAAC;QACX,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACtB,uCAAuC;YACvC,IAAI,CAAC;gBACJ,UAAU,CAAC,OAAO,CAAC,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;YACrC,OAAO,EAAE,CAAC;QACX,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# hyper cookbook info
|
|
2
|
+
|
|
3
|
+
Show detailed information about a cookbook, including its recipes and their variables. Searches all installed kits to locate the cookbook by name.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
`hyper cookbook info <cookbook> [flags]`
|
|
8
|
+
|
|
9
|
+
## Arguments
|
|
10
|
+
|
|
11
|
+
| Argument | Description |
|
|
12
|
+
|----------|-------------|
|
|
13
|
+
| `cookbook` | Cookbook name or path — required |
|
|
14
|
+
|
|
15
|
+
## Flags
|
|
16
|
+
|
|
17
|
+
| Flag | Description |
|
|
18
|
+
|------|-------------|
|
|
19
|
+
| `--json` | Output as JSON |
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
# Show info for a cookbook by name
|
|
25
|
+
hyper cookbook info starlight
|
|
26
|
+
|
|
27
|
+
# Show info using the full kit-qualified path
|
|
28
|
+
hyper cookbook info @kit/starlight/docs --json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Output
|
|
32
|
+
|
|
33
|
+
The default output displays the cookbook's location, kit, description, and a recipe list with each recipe's variables. With `--json`, the full structure is returned as a machine-readable object.
|
|
34
|
+
|
|
35
|
+
If the cookbook is not found, `hyper cookbook info` lists all available cookbooks grouped by kit.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# hyper cookbook list
|
|
2
|
+
|
|
3
|
+
List cookbooks across all installed kits, or filter to a specific kit. Shows each cookbook's name, description, and the recipes it contains.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
`hyper cookbook list [kit] [flags]`
|
|
8
|
+
|
|
9
|
+
## Arguments
|
|
10
|
+
|
|
11
|
+
| Argument | Description |
|
|
12
|
+
|----------|-------------|
|
|
13
|
+
| `kit` | Kit to list cookbooks from — optional, lists all if omitted |
|
|
14
|
+
|
|
15
|
+
## Flags
|
|
16
|
+
|
|
17
|
+
| Flag | Description |
|
|
18
|
+
|------|-------------|
|
|
19
|
+
| `--kit <name>`, `-k` | Filter by kit name (alternative to the positional argument) |
|
|
20
|
+
| `--json` | Output as JSON |
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
# List all cookbooks across all installed kits
|
|
26
|
+
hyper cookbook list
|
|
27
|
+
|
|
28
|
+
# List cookbooks from a specific kit
|
|
29
|
+
hyper cookbook list @kit/starlight
|
|
30
|
+
|
|
31
|
+
# Machine-readable output
|
|
32
|
+
hyper cookbook list --json
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Output
|
|
36
|
+
|
|
37
|
+
Cookbooks are grouped by kit. Each entry shows the cookbook name, version (if set), description, and the names of recipes it contains. With `--json`, the full list is returned as an array.
|
package/help/gen.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# hyper gen
|
|
2
|
+
|
|
3
|
+
Execute a recipe to generate code. Discovers recipes from installed kits, resolves recipe paths, and runs the generation pipeline.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
`hyper gen <recipe> [options]`
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
# Run a local recipe
|
|
13
|
+
hyper gen ./my-recipe
|
|
14
|
+
|
|
15
|
+
# Run a recipe from an installed kit
|
|
16
|
+
hyper gen @kit/starlight/create
|
|
17
|
+
|
|
18
|
+
# Pass variables inline
|
|
19
|
+
hyper gen create-component --name=Button
|
|
20
|
+
|
|
21
|
+
# Provide pre-computed AI answers
|
|
22
|
+
hyper gen ./my-recipe --answers ./ai-answers.json
|
|
23
|
+
|
|
24
|
+
# Shorthand: kit name + recipe path
|
|
25
|
+
hyper nextjs crud update Organization
|
|
26
|
+
```
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# hyper recipe run
|
|
2
|
+
|
|
3
|
+
Execute a recipe to generate code. Runs the full generation pipeline including template rendering, file operations, and optional AI 2-pass generation.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
`hyper recipe run <recipe> [--var=value ...] [flags]`
|
|
8
|
+
|
|
9
|
+
## Arguments
|
|
10
|
+
|
|
11
|
+
| Argument | Description |
|
|
12
|
+
|----------|-------------|
|
|
13
|
+
| `recipe` | Path to recipe file (`.yml` or `.yaml`) — required |
|
|
14
|
+
|
|
15
|
+
## Flags
|
|
16
|
+
|
|
17
|
+
| Flag | Description |
|
|
18
|
+
|------|-------------|
|
|
19
|
+
| `--dry` | Dry run — show what would happen without writing files |
|
|
20
|
+
| `--dry-run` | Alias for `--dry` |
|
|
21
|
+
| `--force`, `-f` | Overwrite existing files |
|
|
22
|
+
| `--skip-prompts` | Skip all interactive prompts |
|
|
23
|
+
| `--defaults` | Use default values for all prompts |
|
|
24
|
+
| `--continue-on-error` | Keep running even if a step fails |
|
|
25
|
+
| `--answers <file>` | Load AI answers from a JSON file (Pass 2) |
|
|
26
|
+
| `--ai-mode <mode>` | AI resolution mode: `me`, `ai`, or `nobody` |
|
|
27
|
+
| `--json` | Output result as JSON |
|
|
28
|
+
| `--verbose`, `-v` | Verbose output |
|
|
29
|
+
| `--quiet`, `-q` | Suppress output |
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
# Run a recipe by path
|
|
35
|
+
hyper recipe run my-recipe.yml
|
|
36
|
+
|
|
37
|
+
# Pass recipe variables inline
|
|
38
|
+
hyper recipe run recipe.yml --name=Button --type=component
|
|
39
|
+
|
|
40
|
+
# Dry run to preview file operations
|
|
41
|
+
hyper recipe run recipe.yml --dry
|
|
42
|
+
|
|
43
|
+
# Use pre-generated AI answers (Pass 2)
|
|
44
|
+
hyper recipe run recipe.yml --answers ./ai-answers.json
|
|
45
|
+
|
|
46
|
+
# Run with a specific AI mode
|
|
47
|
+
hyper recipe run recipe.yml --ai-mode stdout
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Recipe Variables
|
|
51
|
+
|
|
52
|
+
Any unknown `--flag=value` pair is treated as a recipe variable and passed directly to the template engine. For example, `--name=Button` sets the `name` variable in the recipe.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# hyper recipe validate
|
|
2
|
+
|
|
3
|
+
Validate a recipe file's syntax and structure without executing it. Reports the recipe name, version, variable count, and step list on success.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
`hyper recipe validate <recipe> [flags]`
|
|
8
|
+
|
|
9
|
+
## Arguments
|
|
10
|
+
|
|
11
|
+
| Argument | Description |
|
|
12
|
+
|----------|-------------|
|
|
13
|
+
| `recipe` | Path to recipe file (`.yml` or `.yaml`) — required |
|
|
14
|
+
|
|
15
|
+
## Flags
|
|
16
|
+
|
|
17
|
+
| Flag | Description |
|
|
18
|
+
|------|-------------|
|
|
19
|
+
| `--strict` | Strict validation mode |
|
|
20
|
+
| `--json` | Output result as JSON |
|
|
21
|
+
| `--verbose`, `-v` | Verbose output |
|
|
22
|
+
| `--quiet`, `-q` | Suppress output |
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
# Validate a local recipe
|
|
28
|
+
hyper recipe validate my-recipe.yml
|
|
29
|
+
|
|
30
|
+
# Validate a recipe inside a kit
|
|
31
|
+
hyper recipe validate .hyper/kits/component.yml --strict
|
|
32
|
+
|
|
33
|
+
# Machine-readable output
|
|
34
|
+
hyper recipe validate recipe.yml --json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## JSON Output
|
|
38
|
+
|
|
39
|
+
With `--json`, the command outputs a structured object:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"valid": true,
|
|
44
|
+
"name": "Create Component",
|
|
45
|
+
"version": "1.0.0",
|
|
46
|
+
"steps": 4,
|
|
47
|
+
"variables": 2
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
On failure, `valid` is `false` and an `error` field describes the problem.
|