@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,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install Tool Implementation for Recipe Step System
|
|
3
|
+
*
|
|
4
|
+
* Installs packages using the project's package manager.
|
|
5
|
+
* Auto-detects bun/pnpm/yarn/npm from lockfiles.
|
|
6
|
+
*/
|
|
7
|
+
import type { InstallStep, StepContext, StepExecutionOptions, StepResult } from "#recipe-engine/types";
|
|
8
|
+
import { Tool, type ToolValidationResult } from "./base.js";
|
|
9
|
+
export declare class InstallTool extends Tool<InstallStep> {
|
|
10
|
+
constructor(name?: string, options?: Record<string, any>);
|
|
11
|
+
protected onValidate(step: InstallStep, context: StepContext): Promise<ToolValidationResult>;
|
|
12
|
+
protected onExecute(step: InstallStep, context: StepContext, options?: StepExecutionOptions): Promise<StepResult>;
|
|
13
|
+
}
|
|
14
|
+
export declare class InstallToolFactory {
|
|
15
|
+
create(name?: string, options?: Record<string, any>): InstallTool;
|
|
16
|
+
getToolType(): "install";
|
|
17
|
+
validateConfig(config: Record<string, any>): ToolValidationResult;
|
|
18
|
+
}
|
|
19
|
+
export declare const installToolFactory: InstallToolFactory;
|
|
20
|
+
//# sourceMappingURL=install-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-tool.d.ts","sourceRoot":"","sources":["../../../src/recipe-engine/tools/install-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAEX,WAAW,EACX,WAAW,EACX,oBAAoB,EACpB,UAAU,EACV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,KAAK,oBAAoB,EAAE,MAAM,WAAW,CAAC;AA8C5D,qBAAa,WAAY,SAAQ,IAAI,CAAC,WAAW,CAAC;gBACrC,IAAI,SAAiB,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;cAIpD,UAAU,CACzB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,WAAW,GAClB,OAAO,CAAC,oBAAoB,CAAC;cAgChB,SAAS,CACxB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,UAAU,CAAC;CAsGtB;AAED,qBAAa,kBAAkB;IAC9B,MAAM,CAAC,IAAI,SAAiB,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,WAAW;IAI7E,WAAW,IAAI,SAAS;IAIxB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,oBAAoB;CAQjE;AAED,eAAO,MAAM,kBAAkB,oBAA2B,CAAC"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install Tool Implementation for Recipe Step System
|
|
3
|
+
*
|
|
4
|
+
* Installs packages using the project's package manager.
|
|
5
|
+
* Auto-detects bun/pnpm/yarn/npm from lockfiles.
|
|
6
|
+
*/
|
|
7
|
+
import { exec } from "node:child_process";
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { promisify } from "node:util";
|
|
11
|
+
import { Tool } from "./base.js";
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
/**
|
|
14
|
+
* Detect the project's package manager from lockfiles
|
|
15
|
+
*/
|
|
16
|
+
function detectPackageManager(projectRoot) {
|
|
17
|
+
const lockfiles = [
|
|
18
|
+
["bun.lockb", "bun"],
|
|
19
|
+
["bun.lock", "bun"],
|
|
20
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
21
|
+
["yarn.lock", "yarn"],
|
|
22
|
+
["package-lock.json", "npm"],
|
|
23
|
+
];
|
|
24
|
+
for (const [file, pm] of lockfiles) {
|
|
25
|
+
if (fs.existsSync(path.join(projectRoot, file))) {
|
|
26
|
+
return pm;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Default to npm
|
|
30
|
+
return "npm";
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Build the install command for a package manager
|
|
34
|
+
*/
|
|
35
|
+
function buildInstallCommand(pm, packages, dev) {
|
|
36
|
+
const pkgList = packages.join(" ");
|
|
37
|
+
switch (pm) {
|
|
38
|
+
case "bun":
|
|
39
|
+
return `bun add ${dev ? "--dev " : ""}${pkgList}`;
|
|
40
|
+
case "pnpm":
|
|
41
|
+
return `pnpm add ${dev ? "--save-dev " : ""}${pkgList}`;
|
|
42
|
+
case "yarn":
|
|
43
|
+
return `yarn add ${dev ? "--dev " : ""}${pkgList}`;
|
|
44
|
+
case "npm":
|
|
45
|
+
return `npm install ${dev ? "--save-dev " : ""}${pkgList}`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export class InstallTool extends Tool {
|
|
49
|
+
constructor(name = "install-tool", options = {}) {
|
|
50
|
+
super("install", name, options);
|
|
51
|
+
}
|
|
52
|
+
async onValidate(step, context) {
|
|
53
|
+
const errors = [];
|
|
54
|
+
const warnings = [];
|
|
55
|
+
const suggestions = [];
|
|
56
|
+
if (!step.packages || !Array.isArray(step.packages) || step.packages.length === 0) {
|
|
57
|
+
errors.push("At least one package is required");
|
|
58
|
+
}
|
|
59
|
+
if (step.packages) {
|
|
60
|
+
for (const pkg of step.packages) {
|
|
61
|
+
if (typeof pkg !== "string" || pkg.trim() === "") {
|
|
62
|
+
errors.push(`Invalid package name: ${pkg}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
isValid: errors.length === 0,
|
|
68
|
+
errors,
|
|
69
|
+
warnings,
|
|
70
|
+
suggestions,
|
|
71
|
+
estimatedExecutionTime: 10000,
|
|
72
|
+
resourceRequirements: {
|
|
73
|
+
memory: 50 * 1024 * 1024,
|
|
74
|
+
disk: 100 * 1024 * 1024,
|
|
75
|
+
network: true,
|
|
76
|
+
processes: 1,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
async onExecute(step, context, options) {
|
|
81
|
+
const startTime = new Date();
|
|
82
|
+
this.debug("Installing packages: %o", step.packages);
|
|
83
|
+
try {
|
|
84
|
+
const pm = step.packageManager || detectPackageManager(context.projectRoot);
|
|
85
|
+
const dev = step.dev || false;
|
|
86
|
+
const command = buildInstallCommand(pm, step.packages, dev);
|
|
87
|
+
this.debug("Using %s: %s", pm, command);
|
|
88
|
+
if (options?.dryRun || context.dryRun) {
|
|
89
|
+
const endTime = new Date();
|
|
90
|
+
return {
|
|
91
|
+
status: "completed",
|
|
92
|
+
stepName: step.name,
|
|
93
|
+
toolType: "install",
|
|
94
|
+
startTime,
|
|
95
|
+
endTime,
|
|
96
|
+
duration: endTime.getTime() - startTime.getTime(),
|
|
97
|
+
retryCount: 0,
|
|
98
|
+
dependenciesSatisfied: true,
|
|
99
|
+
toolResult: {
|
|
100
|
+
packageManager: pm,
|
|
101
|
+
packages: step.packages,
|
|
102
|
+
dev,
|
|
103
|
+
dryRun: true,
|
|
104
|
+
command,
|
|
105
|
+
},
|
|
106
|
+
output: { command, dryRun: true },
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// Strip CLAUDECODE to avoid "nested session" errors inside Claude Code
|
|
110
|
+
const { CLAUDECODE: _, ...cleanEnv } = process.env;
|
|
111
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
112
|
+
cwd: context.projectRoot,
|
|
113
|
+
env: { ...cleanEnv },
|
|
114
|
+
});
|
|
115
|
+
const endTime = new Date();
|
|
116
|
+
return {
|
|
117
|
+
status: "completed",
|
|
118
|
+
stepName: step.name,
|
|
119
|
+
toolType: "install",
|
|
120
|
+
startTime,
|
|
121
|
+
endTime,
|
|
122
|
+
duration: endTime.getTime() - startTime.getTime(),
|
|
123
|
+
retryCount: 0,
|
|
124
|
+
dependenciesSatisfied: true,
|
|
125
|
+
toolResult: {
|
|
126
|
+
packageManager: pm,
|
|
127
|
+
packages: step.packages,
|
|
128
|
+
dev,
|
|
129
|
+
exitCode: 0,
|
|
130
|
+
stdout: stdout.toString(),
|
|
131
|
+
stderr: stderr.toString(),
|
|
132
|
+
},
|
|
133
|
+
output: { stdout: stdout.toString() },
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
const endTime = new Date();
|
|
138
|
+
const duration = endTime.getTime() - startTime.getTime();
|
|
139
|
+
// If optional, treat failure as completed with warning
|
|
140
|
+
if (step.optional) {
|
|
141
|
+
this.debug("Optional install failed (non-fatal): %s", error.message);
|
|
142
|
+
return {
|
|
143
|
+
status: "completed",
|
|
144
|
+
stepName: step.name,
|
|
145
|
+
toolType: "install",
|
|
146
|
+
startTime,
|
|
147
|
+
endTime,
|
|
148
|
+
duration,
|
|
149
|
+
retryCount: 0,
|
|
150
|
+
dependenciesSatisfied: true,
|
|
151
|
+
toolResult: {
|
|
152
|
+
packages: step.packages,
|
|
153
|
+
optional: true,
|
|
154
|
+
warning: `Install failed (optional): ${error.message}`,
|
|
155
|
+
},
|
|
156
|
+
output: { warning: error.message },
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
status: "failed",
|
|
161
|
+
stepName: step.name,
|
|
162
|
+
toolType: "install",
|
|
163
|
+
startTime,
|
|
164
|
+
endTime,
|
|
165
|
+
duration,
|
|
166
|
+
retryCount: 0,
|
|
167
|
+
dependenciesSatisfied: true,
|
|
168
|
+
error: {
|
|
169
|
+
message: error.message,
|
|
170
|
+
code: "INSTALL_FAILED",
|
|
171
|
+
cause: error,
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
export class InstallToolFactory {
|
|
178
|
+
create(name = "install-tool", options = {}) {
|
|
179
|
+
return new InstallTool(name, options);
|
|
180
|
+
}
|
|
181
|
+
getToolType() {
|
|
182
|
+
return "install";
|
|
183
|
+
}
|
|
184
|
+
validateConfig(config) {
|
|
185
|
+
return {
|
|
186
|
+
isValid: true,
|
|
187
|
+
errors: [],
|
|
188
|
+
warnings: [],
|
|
189
|
+
suggestions: [],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
export const installToolFactory = new InstallToolFactory();
|
|
194
|
+
//# sourceMappingURL=install-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-tool.js","sourceRoot":"","sources":["../../../src/recipe-engine/tools/install-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parallel Tool Implementation for Recipe Step System
|
|
3
|
+
*
|
|
4
|
+
* This tool executes a list of recipe steps concurrently.
|
|
5
|
+
* It leverages the StepExecutor's parallel execution capabilities.
|
|
6
|
+
*/
|
|
7
|
+
import type { ParallelStep, StepContext, StepExecutionOptions, StepResult } from "#recipe-engine/types";
|
|
8
|
+
import { Tool, type ToolValidationResult } from "./base.js";
|
|
9
|
+
export declare class ParallelTool extends Tool<ParallelStep> {
|
|
10
|
+
constructor(name?: string, options?: Record<string, any>);
|
|
11
|
+
protected onValidate(step: ParallelStep, context: StepContext): Promise<ToolValidationResult>;
|
|
12
|
+
protected onExecute(step: ParallelStep, context: StepContext, options?: StepExecutionOptions): Promise<StepResult>;
|
|
13
|
+
private createResult;
|
|
14
|
+
}
|
|
15
|
+
export declare class ParallelToolFactory {
|
|
16
|
+
create(name?: string, options?: Record<string, any>): ParallelTool;
|
|
17
|
+
getToolType(): "parallel";
|
|
18
|
+
validateConfig(config: Record<string, any>): ToolValidationResult;
|
|
19
|
+
}
|
|
20
|
+
export declare const parallelToolFactory: ParallelToolFactory;
|
|
21
|
+
//# sourceMappingURL=parallel-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parallel-tool.d.ts","sourceRoot":"","sources":["../../../src/recipe-engine/tools/parallel-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAEX,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,UAAU,EACV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,KAAK,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAE5D,qBAAa,YAAa,SAAQ,IAAI,CAAC,YAAY,CAAC;gBACvC,IAAI,SAAkB,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;cAIrD,UAAU,CACzB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,WAAW,GAClB,OAAO,CAAC,oBAAoB,CAAC;cA0BhB,SAAS,CACxB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,UAAU,CAAC;IAyDtB,OAAO,CAAC,YAAY;CAwCpB;AAED,qBAAa,mBAAmB;IAC/B,MAAM,CAAC,IAAI,SAAkB,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,YAAY;IAI/E,WAAW,IAAI,UAAU;IAIzB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,oBAAoB;CAQjE;AAED,eAAO,MAAM,mBAAmB,qBAA4B,CAAC"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parallel Tool Implementation for Recipe Step System
|
|
3
|
+
*
|
|
4
|
+
* This tool executes a list of recipe steps concurrently.
|
|
5
|
+
* It leverages the StepExecutor's parallel execution capabilities.
|
|
6
|
+
*/
|
|
7
|
+
import { ErrorCode, ErrorHandler } from "@hypercli/core";
|
|
8
|
+
import { StepExecutor } from "#recipe-engine/step-executor";
|
|
9
|
+
import { Tool } from "./base.js";
|
|
10
|
+
export class ParallelTool extends Tool {
|
|
11
|
+
constructor(name = "parallel-tool", options = {}) {
|
|
12
|
+
super("parallel", name, options);
|
|
13
|
+
}
|
|
14
|
+
async onValidate(step, context) {
|
|
15
|
+
const errors = [];
|
|
16
|
+
if (!step.steps || !Array.isArray(step.steps) || step.steps.length === 0) {
|
|
17
|
+
errors.push("Parallel steps must be a non-empty array");
|
|
18
|
+
}
|
|
19
|
+
if (step.limit && (typeof step.limit !== "number" || step.limit <= 0)) {
|
|
20
|
+
errors.push("Parallel limit must be a positive number");
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
isValid: errors.length === 0,
|
|
24
|
+
errors,
|
|
25
|
+
warnings: [],
|
|
26
|
+
suggestions: [],
|
|
27
|
+
estimatedExecutionTime: 0, // Hard to estimate for parallel
|
|
28
|
+
resourceRequirements: {
|
|
29
|
+
memory: 0, // Dynamically determined by steps
|
|
30
|
+
disk: 0,
|
|
31
|
+
network: false,
|
|
32
|
+
processes: 0,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async onExecute(step, context, options) {
|
|
37
|
+
const startTime = new Date();
|
|
38
|
+
this.debug("Executing parallel step: %s with %d steps", step.name, step.steps.length);
|
|
39
|
+
try {
|
|
40
|
+
const executor = new StepExecutor(undefined, {
|
|
41
|
+
collectMetrics: false,
|
|
42
|
+
enableProgressTracking: false,
|
|
43
|
+
maxConcurrency: step.limit,
|
|
44
|
+
enableParallelExecution: true,
|
|
45
|
+
});
|
|
46
|
+
// If continueOnError is explicitly set to false (failedFast behavior), passing it to StepExecutor
|
|
47
|
+
// might need to be verified. StepExecutor's continueOnError typically means "continue execution of valid steps".
|
|
48
|
+
// For parallel execution, we want "if one fails, abort others" or "wait for all".
|
|
49
|
+
// The `StepExecutor` likely handles dependencies, but if we pass a flat list without deps, it can run them efficiently.
|
|
50
|
+
const executionOptions = {
|
|
51
|
+
...options,
|
|
52
|
+
continueOnError: step.continueOnError ?? options?.continueOnError,
|
|
53
|
+
};
|
|
54
|
+
const results = await executor.executeSteps(step.steps, context, executionOptions);
|
|
55
|
+
const failed = results.filter((r) => r.status === "failed");
|
|
56
|
+
if (failed.length > 0 && !executionOptions.continueOnError) {
|
|
57
|
+
throw ErrorHandler.createError(ErrorCode.TEMPLATE_EXECUTION_ERROR, `Parallel execution failed: ${failed.map((f) => f.stepName).join(", ")}`, { template: step.name, cause: failed[0].error });
|
|
58
|
+
}
|
|
59
|
+
this.debug("Parallel execution completed");
|
|
60
|
+
return this.createResult(step, results, startTime, "completed");
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
const endTime = new Date();
|
|
64
|
+
return {
|
|
65
|
+
status: "failed",
|
|
66
|
+
stepName: step.name,
|
|
67
|
+
toolType: "parallel",
|
|
68
|
+
startTime,
|
|
69
|
+
endTime,
|
|
70
|
+
duration: endTime.getTime() - startTime.getTime(),
|
|
71
|
+
retryCount: 0,
|
|
72
|
+
dependenciesSatisfied: true,
|
|
73
|
+
error: {
|
|
74
|
+
message: error.message,
|
|
75
|
+
code: error.code || "PARALLEL_EXECUTION_ERROR",
|
|
76
|
+
cause: error,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
createResult(step, results, startTime, status) {
|
|
82
|
+
const endTime = new Date();
|
|
83
|
+
const filesCreated = [];
|
|
84
|
+
const filesModified = [];
|
|
85
|
+
const filesDeleted = [];
|
|
86
|
+
results.forEach((r) => {
|
|
87
|
+
if (r.filesCreated)
|
|
88
|
+
filesCreated.push(...r.filesCreated);
|
|
89
|
+
if (r.filesModified)
|
|
90
|
+
filesModified.push(...r.filesModified);
|
|
91
|
+
if (r.filesDeleted)
|
|
92
|
+
filesDeleted.push(...r.filesDeleted);
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
status,
|
|
96
|
+
stepName: step.name,
|
|
97
|
+
toolType: "parallel",
|
|
98
|
+
startTime,
|
|
99
|
+
endTime,
|
|
100
|
+
duration: endTime.getTime() - startTime.getTime(),
|
|
101
|
+
retryCount: 0,
|
|
102
|
+
dependenciesSatisfied: true,
|
|
103
|
+
filesCreated,
|
|
104
|
+
filesModified,
|
|
105
|
+
filesDeleted,
|
|
106
|
+
toolResult: {
|
|
107
|
+
steps: results,
|
|
108
|
+
},
|
|
109
|
+
output: {
|
|
110
|
+
totalSteps: results.length,
|
|
111
|
+
completed: results.filter((r) => r.status === "completed").length,
|
|
112
|
+
failed: results.filter((r) => r.status === "failed").length,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export class ParallelToolFactory {
|
|
118
|
+
create(name = "parallel-tool", options = {}) {
|
|
119
|
+
return new ParallelTool(name, options);
|
|
120
|
+
}
|
|
121
|
+
getToolType() {
|
|
122
|
+
return "parallel";
|
|
123
|
+
}
|
|
124
|
+
validateConfig(config) {
|
|
125
|
+
return {
|
|
126
|
+
isValid: true,
|
|
127
|
+
errors: [],
|
|
128
|
+
warnings: [],
|
|
129
|
+
suggestions: [],
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export const parallelToolFactory = new ParallelToolFactory();
|
|
134
|
+
//# sourceMappingURL=parallel-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parallel-tool.js","sourceRoot":"","sources":["../../../src/recipe-engine/tools/parallel-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Patch Tool Implementation for Recipe Step System
|
|
3
|
+
*
|
|
4
|
+
* Deep-merges structured data into existing files (JSON, YAML, TOML).
|
|
5
|
+
* Creates the file if it doesn't exist (configurable).
|
|
6
|
+
*/
|
|
7
|
+
import type { PatchStep, StepContext, StepExecutionOptions, StepResult } from "#recipe-engine/types";
|
|
8
|
+
import { Tool, type ToolValidationResult } from "./base.js";
|
|
9
|
+
export declare class PatchTool extends Tool<PatchStep> {
|
|
10
|
+
constructor(name?: string, options?: Record<string, any>);
|
|
11
|
+
protected onValidate(step: PatchStep, context: StepContext): Promise<ToolValidationResult>;
|
|
12
|
+
protected onExecute(step: PatchStep, context: StepContext, options?: StepExecutionOptions): Promise<StepResult>;
|
|
13
|
+
private resolveVariablesInObject;
|
|
14
|
+
}
|
|
15
|
+
export declare class PatchToolFactory {
|
|
16
|
+
create(name?: string, options?: Record<string, any>): PatchTool;
|
|
17
|
+
getToolType(): "patch";
|
|
18
|
+
validateConfig(config: Record<string, any>): ToolValidationResult;
|
|
19
|
+
}
|
|
20
|
+
export declare const patchToolFactory: PatchToolFactory;
|
|
21
|
+
//# sourceMappingURL=patch-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch-tool.d.ts","sourceRoot":"","sources":["../../../src/recipe-engine/tools/patch-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAEX,SAAS,EACT,WAAW,EACX,oBAAoB,EACpB,UAAU,EACV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,KAAK,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAsG5D,qBAAa,SAAU,SAAQ,IAAI,CAAC,SAAS,CAAC;gBACjC,IAAI,SAAe,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;cAIlD,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;cAqChF,SAAS,CACxB,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,UAAU,CAAC;IAmFtB,OAAO,CAAC,wBAAwB;CAoBhC;AAED,qBAAa,gBAAgB;IAC5B,MAAM,CAAC,IAAI,SAAe,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,SAAS;IAIzE,WAAW,IAAI,OAAO;IAItB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,oBAAoB;CAQjE;AAED,eAAO,MAAM,gBAAgB,kBAAyB,CAAC"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Patch Tool Implementation for Recipe Step System
|
|
3
|
+
*
|
|
4
|
+
* Deep-merges structured data into existing files (JSON, YAML, TOML).
|
|
5
|
+
* Creates the file if it doesn't exist (configurable).
|
|
6
|
+
*/
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { Tool } from "./base.js";
|
|
10
|
+
/**
|
|
11
|
+
* Auto-detect file format from extension
|
|
12
|
+
*/
|
|
13
|
+
function detectFormat(filePath) {
|
|
14
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
15
|
+
switch (ext) {
|
|
16
|
+
case ".json":
|
|
17
|
+
return "json";
|
|
18
|
+
case ".yml":
|
|
19
|
+
case ".yaml":
|
|
20
|
+
return "yaml";
|
|
21
|
+
case ".toml":
|
|
22
|
+
return "toml";
|
|
23
|
+
default:
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Deep merge source into target, mutating target.
|
|
29
|
+
* Arrays are replaced, not concatenated.
|
|
30
|
+
*/
|
|
31
|
+
function deepMerge(target, source) {
|
|
32
|
+
for (const key of Object.keys(source)) {
|
|
33
|
+
const srcVal = source[key];
|
|
34
|
+
const tgtVal = target[key];
|
|
35
|
+
if (srcVal !== null &&
|
|
36
|
+
typeof srcVal === "object" &&
|
|
37
|
+
!Array.isArray(srcVal) &&
|
|
38
|
+
tgtVal !== null &&
|
|
39
|
+
typeof tgtVal === "object" &&
|
|
40
|
+
!Array.isArray(tgtVal)) {
|
|
41
|
+
target[key] = deepMerge(tgtVal, srcVal);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
target[key] = srcVal;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return target;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Parse file content based on format
|
|
51
|
+
*/
|
|
52
|
+
async function parseFile(content, format) {
|
|
53
|
+
switch (format) {
|
|
54
|
+
case "json":
|
|
55
|
+
return JSON.parse(content);
|
|
56
|
+
case "yaml": {
|
|
57
|
+
const { parse } = await import("yaml");
|
|
58
|
+
return parse(content) ?? {};
|
|
59
|
+
}
|
|
60
|
+
case "toml": {
|
|
61
|
+
try {
|
|
62
|
+
// @ts-ignore -- optional dependency, only needed for TOML files
|
|
63
|
+
const { parse } = await import("smol-toml");
|
|
64
|
+
return parse(content);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
throw new Error('TOML parsing requires the "smol-toml" package. Install it with: bun add smol-toml');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
default:
|
|
71
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Serialize data to string based on format
|
|
76
|
+
*/
|
|
77
|
+
async function serializeFile(data, format, indent) {
|
|
78
|
+
switch (format) {
|
|
79
|
+
case "json":
|
|
80
|
+
return `${JSON.stringify(data, null, indent)}\n`;
|
|
81
|
+
case "yaml": {
|
|
82
|
+
const { stringify } = await import("yaml");
|
|
83
|
+
return stringify(data, { indent });
|
|
84
|
+
}
|
|
85
|
+
case "toml": {
|
|
86
|
+
try {
|
|
87
|
+
// @ts-ignore -- optional dependency, only needed for TOML files
|
|
88
|
+
const { stringify } = await import("smol-toml");
|
|
89
|
+
return `${stringify(data)}\n`;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
throw new Error('TOML serialization requires the "smol-toml" package. Install it with: bun add smol-toml');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
default:
|
|
96
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export class PatchTool extends Tool {
|
|
100
|
+
constructor(name = "patch-tool", options = {}) {
|
|
101
|
+
super("patch", name, options);
|
|
102
|
+
}
|
|
103
|
+
async onValidate(step, context) {
|
|
104
|
+
const errors = [];
|
|
105
|
+
const warnings = [];
|
|
106
|
+
const suggestions = [];
|
|
107
|
+
if (!step.file) {
|
|
108
|
+
errors.push("File path is required");
|
|
109
|
+
}
|
|
110
|
+
if (!step.merge || typeof step.merge !== "object" || Array.isArray(step.merge)) {
|
|
111
|
+
errors.push('"merge" must be a non-null object');
|
|
112
|
+
}
|
|
113
|
+
const format = step.format || (step.file ? detectFormat(step.file) : undefined);
|
|
114
|
+
if (step.file && !format) {
|
|
115
|
+
errors.push(`Cannot detect format for "${step.file}". Specify "format" explicitly.`);
|
|
116
|
+
}
|
|
117
|
+
if (format && !["json", "yaml", "toml"].includes(format)) {
|
|
118
|
+
errors.push(`Unsupported format: ${format}. Must be one of: json, yaml, toml`);
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
isValid: errors.length === 0,
|
|
122
|
+
errors,
|
|
123
|
+
warnings,
|
|
124
|
+
suggestions,
|
|
125
|
+
estimatedExecutionTime: 200,
|
|
126
|
+
resourceRequirements: {
|
|
127
|
+
memory: 5 * 1024 * 1024,
|
|
128
|
+
disk: 1024,
|
|
129
|
+
network: false,
|
|
130
|
+
processes: 0,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
async onExecute(step, context, options) {
|
|
135
|
+
const startTime = new Date();
|
|
136
|
+
this.debug("Patching file: %s", step.file);
|
|
137
|
+
try {
|
|
138
|
+
const filePath = path.resolve(context.projectRoot, step.file);
|
|
139
|
+
const format = step.format || detectFormat(step.file);
|
|
140
|
+
const indent = step.indent ?? 2;
|
|
141
|
+
const createIfMissing = step.createIfMissing ?? true;
|
|
142
|
+
if (!format) {
|
|
143
|
+
throw new Error(`Cannot detect format for "${step.file}". Specify "format" explicitly.`);
|
|
144
|
+
}
|
|
145
|
+
let existing = {};
|
|
146
|
+
let created = false;
|
|
147
|
+
if (fs.existsSync(filePath)) {
|
|
148
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
149
|
+
existing = await parseFile(content, format);
|
|
150
|
+
}
|
|
151
|
+
else if (createIfMissing) {
|
|
152
|
+
created = true;
|
|
153
|
+
// Ensure parent directory exists
|
|
154
|
+
const dir = path.dirname(filePath);
|
|
155
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
throw new Error(`File not found: ${step.file} (createIfMissing is false)`);
|
|
159
|
+
}
|
|
160
|
+
// Resolve variables in merge data
|
|
161
|
+
const resolvedMerge = this.resolveVariablesInObject(step.merge, context.variables);
|
|
162
|
+
// Deep merge
|
|
163
|
+
const merged = deepMerge(existing, resolvedMerge);
|
|
164
|
+
// Write back
|
|
165
|
+
if (!(options?.dryRun || context.dryRun)) {
|
|
166
|
+
const serialized = await serializeFile(merged, format, indent);
|
|
167
|
+
fs.writeFileSync(filePath, serialized, "utf-8");
|
|
168
|
+
}
|
|
169
|
+
const endTime = new Date();
|
|
170
|
+
const patchResult = {
|
|
171
|
+
file: step.file,
|
|
172
|
+
format,
|
|
173
|
+
created,
|
|
174
|
+
merged: resolvedMerge,
|
|
175
|
+
};
|
|
176
|
+
return {
|
|
177
|
+
status: "completed",
|
|
178
|
+
stepName: step.name,
|
|
179
|
+
toolType: "patch",
|
|
180
|
+
startTime,
|
|
181
|
+
endTime,
|
|
182
|
+
duration: endTime.getTime() - startTime.getTime(),
|
|
183
|
+
retryCount: 0,
|
|
184
|
+
dependenciesSatisfied: true,
|
|
185
|
+
toolResult: patchResult,
|
|
186
|
+
filesModified: created ? undefined : [filePath],
|
|
187
|
+
filesCreated: created ? [filePath] : undefined,
|
|
188
|
+
output: { file: step.file, created, format },
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
const endTime = new Date();
|
|
193
|
+
return {
|
|
194
|
+
status: "failed",
|
|
195
|
+
stepName: step.name,
|
|
196
|
+
toolType: "patch",
|
|
197
|
+
startTime,
|
|
198
|
+
endTime,
|
|
199
|
+
duration: endTime.getTime() - startTime.getTime(),
|
|
200
|
+
retryCount: 0,
|
|
201
|
+
dependenciesSatisfied: true,
|
|
202
|
+
error: {
|
|
203
|
+
message: error.message,
|
|
204
|
+
code: "PATCH_FAILED",
|
|
205
|
+
cause: error,
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
resolveVariablesInObject(obj, variables) {
|
|
211
|
+
if (typeof obj === "string") {
|
|
212
|
+
return obj.replace(/\{\{\s*([^}]+)\s*\}\}/g, (_, key) => {
|
|
213
|
+
const trimmed = key.trim();
|
|
214
|
+
const value = trimmed.split(".").reduce((o, k) => o?.[k], variables);
|
|
215
|
+
return value !== undefined ? String(value) : `{{${trimmed}}}`;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
if (Array.isArray(obj)) {
|
|
219
|
+
return obj.map((item) => this.resolveVariablesInObject(item, variables));
|
|
220
|
+
}
|
|
221
|
+
if (obj !== null && typeof obj === "object") {
|
|
222
|
+
const result = {};
|
|
223
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
224
|
+
result[key] = this.resolveVariablesInObject(val, variables);
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
return obj;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
export class PatchToolFactory {
|
|
232
|
+
create(name = "patch-tool", options = {}) {
|
|
233
|
+
return new PatchTool(name, options);
|
|
234
|
+
}
|
|
235
|
+
getToolType() {
|
|
236
|
+
return "patch";
|
|
237
|
+
}
|
|
238
|
+
validateConfig(config) {
|
|
239
|
+
return {
|
|
240
|
+
isValid: true,
|
|
241
|
+
errors: [],
|
|
242
|
+
warnings: [],
|
|
243
|
+
suggestions: [],
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
export const patchToolFactory = new PatchToolFactory();
|
|
248
|
+
//# sourceMappingURL=patch-tool.js.map
|