@agenticflow/cli 0.0.1-beta.13

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.
Files changed (105) hide show
  1. package/README.md +125 -0
  2. package/TECHNICAL_DEBT.md +121 -0
  3. package/dist/builder/bundler.d.ts +17 -0
  4. package/dist/builder/bundler.d.ts.map +1 -0
  5. package/dist/builder/bundler.js +170 -0
  6. package/dist/builder/bundler.js.map +1 -0
  7. package/dist/builder/index.d.ts +6 -0
  8. package/dist/builder/index.d.ts.map +1 -0
  9. package/dist/builder/index.js +6 -0
  10. package/dist/builder/index.js.map +1 -0
  11. package/dist/builder/packager.d.ts +41 -0
  12. package/dist/builder/packager.d.ts.map +1 -0
  13. package/dist/builder/packager.js +145 -0
  14. package/dist/builder/packager.js.map +1 -0
  15. package/dist/builder/security.d.ts +26 -0
  16. package/dist/builder/security.d.ts.map +1 -0
  17. package/dist/builder/security.js +204 -0
  18. package/dist/builder/security.js.map +1 -0
  19. package/dist/builder/stripper.d.ts +19 -0
  20. package/dist/builder/stripper.d.ts.map +1 -0
  21. package/dist/builder/stripper.js +100 -0
  22. package/dist/builder/stripper.js.map +1 -0
  23. package/dist/builder/validator.d.ts +33 -0
  24. package/dist/builder/validator.d.ts.map +1 -0
  25. package/dist/builder/validator.js +150 -0
  26. package/dist/builder/validator.js.map +1 -0
  27. package/dist/cli/build.d.ts +3 -0
  28. package/dist/cli/build.d.ts.map +1 -0
  29. package/dist/cli/build.js +167 -0
  30. package/dist/cli/build.js.map +1 -0
  31. package/dist/cli/categories.d.ts +40 -0
  32. package/dist/cli/categories.d.ts.map +1 -0
  33. package/dist/cli/categories.js +101 -0
  34. package/dist/cli/categories.js.map +1 -0
  35. package/dist/cli/dev.d.ts +3 -0
  36. package/dist/cli/dev.d.ts.map +1 -0
  37. package/dist/cli/dev.js +226 -0
  38. package/dist/cli/dev.js.map +1 -0
  39. package/dist/cli/handler-types.d.ts +34 -0
  40. package/dist/cli/handler-types.d.ts.map +1 -0
  41. package/dist/cli/handler-types.js +67 -0
  42. package/dist/cli/handler-types.js.map +1 -0
  43. package/dist/cli/index.d.ts +3 -0
  44. package/dist/cli/index.d.ts.map +1 -0
  45. package/dist/cli/index.js +24 -0
  46. package/dist/cli/index.js.map +1 -0
  47. package/dist/cli/init.d.ts +3 -0
  48. package/dist/cli/init.d.ts.map +1 -0
  49. package/dist/cli/init.js +264 -0
  50. package/dist/cli/init.js.map +1 -0
  51. package/dist/cli/login.d.ts +3 -0
  52. package/dist/cli/login.d.ts.map +1 -0
  53. package/dist/cli/login.js +10 -0
  54. package/dist/cli/login.js.map +1 -0
  55. package/dist/cli/publish.d.ts +5 -0
  56. package/dist/cli/publish.d.ts.map +1 -0
  57. package/dist/cli/publish.js +120 -0
  58. package/dist/cli/publish.js.map +1 -0
  59. package/dist/cli/template-processor.d.ts +35 -0
  60. package/dist/cli/template-processor.d.ts.map +1 -0
  61. package/dist/cli/template-processor.js +82 -0
  62. package/dist/cli/template-processor.js.map +1 -0
  63. package/dist/cli/test.d.ts +3 -0
  64. package/dist/cli/test.d.ts.map +1 -0
  65. package/dist/cli/test.js +12 -0
  66. package/dist/cli/test.js.map +1 -0
  67. package/dist/dev/decorators.d.ts +10 -0
  68. package/dist/dev/decorators.d.ts.map +1 -0
  69. package/dist/dev/decorators.js +26 -0
  70. package/dist/dev/decorators.js.map +1 -0
  71. package/dist/dev/executor.d.ts +22 -0
  72. package/dist/dev/executor.d.ts.map +1 -0
  73. package/dist/dev/executor.js +243 -0
  74. package/dist/dev/executor.js.map +1 -0
  75. package/dist/dev/extractor.d.ts +15 -0
  76. package/dist/dev/extractor.d.ts.map +1 -0
  77. package/dist/dev/extractor.js +224 -0
  78. package/dist/dev/extractor.js.map +1 -0
  79. package/dist/dev/index.d.ts +3 -0
  80. package/dist/dev/index.d.ts.map +1 -0
  81. package/dist/dev/index.js +4 -0
  82. package/dist/dev/index.js.map +1 -0
  83. package/dist/dev/server.d.ts +91 -0
  84. package/dist/dev/server.d.ts.map +1 -0
  85. package/dist/dev/server.js +507 -0
  86. package/dist/dev/server.js.map +1 -0
  87. package/dist/dev/ui-dist/assets/index-BkKxvzfq.js +246 -0
  88. package/dist/dev/ui-dist/assets/index-DTO1qt7B.css +1 -0
  89. package/dist/dev/ui-dist/index.html +14 -0
  90. package/dist/dev/ui-dist/monkey.svg +3 -0
  91. package/dist/dev/ui-dist/package.json +27 -0
  92. package/dist/templates/_shared/.env.template +16 -0
  93. package/dist/templates/_shared/.gitignore.template +46 -0
  94. package/dist/templates/_shared/LICENSE.template +21 -0
  95. package/dist/templates/_shared/src/utils.ts.template +29 -0
  96. package/dist/templates/_shared/tsconfig.json.template +23 -0
  97. package/dist/templates/stateful/manifest.json.template +63 -0
  98. package/dist/templates/stateful/package.json.template +23 -0
  99. package/dist/templates/stateful/src/index.ts.template +147 -0
  100. package/dist/templates/stateless/docs/README.md.template +102 -0
  101. package/dist/templates/stateless/manifest.json.template +63 -0
  102. package/dist/templates/stateless/package.json.template +23 -0
  103. package/dist/templates/stateless/src/index.ts.template +103 -0
  104. package/package.json +51 -0
  105. package/vitest.config.ts +15 -0
@@ -0,0 +1,82 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { getCategoryColor, getCategoryApiValue } from './categories.js';
4
+ /**
5
+ * Process template context with derived values
6
+ */
7
+ export function processTemplateContext(context) {
8
+ return {
9
+ ...context,
10
+ handlerClassName: toPascalCase(context.handlerType),
11
+ handlerTypeFirstWord: context.handlerType.split('-')[0],
12
+ categoryColor: getCategoryColor(context.category),
13
+ categoryApi: getCategoryApiValue(context.category),
14
+ authorGitHub: context.authorName.toLowerCase().replace(/\s+/g, ''),
15
+ currentYear: new Date().getFullYear()
16
+ };
17
+ }
18
+ /**
19
+ * Replace template variables in content
20
+ */
21
+ export function replaceTemplateVariables(content, context) {
22
+ let result = content;
23
+ // Replace all template variables
24
+ Object.entries(context).forEach(([key, value]) => {
25
+ const placeholder = `{{${key}}}`;
26
+ result = result.replace(new RegExp(placeholder, 'g'), String(value));
27
+ });
28
+ return result;
29
+ }
30
+ /**
31
+ * Copy and process a template file
32
+ */
33
+ export async function processTemplateFile(templatePath, outputPath, context) {
34
+ const content = fs.readFileSync(templatePath, 'utf-8');
35
+ const processedContent = replaceTemplateVariables(content, context);
36
+ // Ensure output directory exists
37
+ const outputDir = path.dirname(outputPath);
38
+ fs.mkdirSync(outputDir, { recursive: true });
39
+ fs.writeFileSync(outputPath, processedContent, 'utf-8');
40
+ }
41
+ /**
42
+ * Copy and process an entire template directory
43
+ */
44
+ export async function processTemplateDirectory(templateDir, outputDir, context) {
45
+ const files = await getTemplateFiles(templateDir);
46
+ for (const file of files) {
47
+ const templatePath = path.join(templateDir, file);
48
+ const outputPath = path.join(outputDir, file.replace('.template', ''));
49
+ await processTemplateFile(templatePath, outputPath, context);
50
+ }
51
+ }
52
+ /**
53
+ * Get all template files recursively
54
+ */
55
+ async function getTemplateFiles(dir) {
56
+ const files = [];
57
+ function walk(currentDir, relativePath = '') {
58
+ const entries = fs.readdirSync(currentDir, { withFileTypes: true });
59
+ for (const entry of entries) {
60
+ const fullPath = path.join(currentDir, entry.name);
61
+ const relPath = path.join(relativePath, entry.name);
62
+ if (entry.isDirectory()) {
63
+ walk(fullPath, relPath);
64
+ }
65
+ else if (entry.name.endsWith('.template')) {
66
+ files.push(relPath);
67
+ }
68
+ }
69
+ }
70
+ walk(dir);
71
+ return files;
72
+ }
73
+ /**
74
+ * Convert kebab-case to PascalCase
75
+ */
76
+ function toPascalCase(str) {
77
+ return str
78
+ .split('-')
79
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
80
+ .join('');
81
+ }
82
+ //# sourceMappingURL=template-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-processor.js","sourceRoot":"","sources":["../../src/cli/template-processor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const testCommand: Command;
3
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/cli/test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,WAAW,SAQpB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ export const testCommand = new Command('test')
4
+ .description('Run unit tests for the handler')
5
+ .option('--watch', 'Watch mode')
6
+ .option('--coverage', 'Generate coverage report')
7
+ .action(async (options) => {
8
+ console.log(chalk.blue('\n🧪 Running tests\n'));
9
+ console.log(chalk.yellow('⚠ Test runner not yet implemented'));
10
+ console.log(chalk.dim('Coming soon...\n'));
11
+ });
12
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/cli/test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,gCAAgC,CAAC;KAC7C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC;KAC/B,MAAM,CAAC,YAAY,EAAE,0BAA0B,CAAC;KAChD,MAAM,CAAC,KAAK,EAAE,OAAgD,EAAE,EAAE;IACjE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,mCAAmC,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Dev-time decorator for providing test values.
3
+ * STRIPPED DURING BUILD - Never ships to production.
4
+ */
5
+ export declare function TestValue(value: any): PropertyDecorator;
6
+ /**
7
+ * Extract test values from a handler class
8
+ */
9
+ export declare function extractTestValues(handlerClass: any): Record<string, any>;
10
+ //# sourceMappingURL=decorators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/dev/decorators.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,iBAAiB,CAOvD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAYxE"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Dev-time decorator for providing test values.
3
+ * STRIPPED DURING BUILD - Never ships to production.
4
+ */
5
+ export function TestValue(value) {
6
+ return (target, propertyKey) => {
7
+ if (!target.constructor.__testValues) {
8
+ target.constructor.__testValues = {};
9
+ }
10
+ target.constructor.__testValues[propertyKey] = value;
11
+ };
12
+ }
13
+ /**
14
+ * Extract test values from a handler class
15
+ */
16
+ export function extractTestValues(handlerClass) {
17
+ const testValues = handlerClass.__testValues || {};
18
+ return Object.fromEntries(Object.entries(testValues).map(([key, value]) => {
19
+ // Resolve functions
20
+ if (typeof value === 'function') {
21
+ return [key, value()];
22
+ }
23
+ return [key, value];
24
+ }));
25
+ }
26
+ //# sourceMappingURL=decorators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/dev/decorators.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAU;IAClC,OAAO,CAAC,MAAW,EAAE,WAA4B,EAAE,EAAE;QACnD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;YACrC,MAAM,CAAC,WAAW,CAAC,YAAY,GAAG,EAAE,CAAC;QACvC,CAAC;QACD,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAAiB;IACjD,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,IAAI,EAAE,CAAC;IAEnD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC9C,oBAAoB;QACpB,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACtB,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ export interface ExecutionResult {
2
+ success: boolean;
3
+ duration: number;
4
+ output?: any;
5
+ error?: {
6
+ message: string;
7
+ stack?: string;
8
+ code?: string;
9
+ };
10
+ logs: string[];
11
+ timestamp: string;
12
+ }
13
+ export interface ExecutionOptions {
14
+ inputs: Record<string, any>;
15
+ testValues: Record<string, any>;
16
+ timeout?: number;
17
+ }
18
+ /**
19
+ * Execute a handler in a child process using tsx
20
+ */
21
+ export declare function executeHandler(projectDir: string, options: ExecutionOptions): Promise<ExecutionResult>;
22
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/dev/executor.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CA0I1B"}
@@ -0,0 +1,243 @@
1
+ import { spawn } from 'child_process';
2
+ import * as path from 'path';
3
+ import * as fs from 'fs';
4
+ import * as os from 'os';
5
+ /**
6
+ * Execute a handler in a child process using tsx
7
+ */
8
+ export async function executeHandler(projectDir, options) {
9
+ const startTime = Date.now();
10
+ const logs = [];
11
+ // Create a temporary runner script
12
+ const runnerCode = generateRunnerScript(projectDir, options);
13
+ const tempDir = path.join(os.tmpdir(), 'afh-runner');
14
+ if (!fs.existsSync(tempDir)) {
15
+ fs.mkdirSync(tempDir, { recursive: true });
16
+ }
17
+ const runnerId = `runner-${Date.now()}-${Math.random().toString(36).slice(2)}`;
18
+ const runnerPath = path.join(tempDir, `${runnerId}.ts`);
19
+ fs.writeFileSync(runnerPath, runnerCode);
20
+ return new Promise((resolve) => {
21
+ let stdout = '';
22
+ let stderr = '';
23
+ let timedOut = false;
24
+ const timeout = options.timeout || 30000;
25
+ // Run with tsx
26
+ const child = spawn('npx', ['tsx', runnerPath], {
27
+ cwd: projectDir,
28
+ env: {
29
+ ...process.env,
30
+ // Pass test values as env vars
31
+ AFH_TEST_VALUES: JSON.stringify(options.testValues),
32
+ AFH_INPUTS: JSON.stringify(options.inputs),
33
+ },
34
+ shell: true,
35
+ });
36
+ const timeoutId = setTimeout(() => {
37
+ timedOut = true;
38
+ child.kill('SIGTERM');
39
+ }, timeout);
40
+ child.stdout?.on('data', (data) => {
41
+ const text = data.toString();
42
+ stdout += text;
43
+ // Collect console.log output
44
+ text.split('\n').filter(Boolean).forEach(line => {
45
+ if (!line.startsWith('__AFH_RESULT__:')) {
46
+ logs.push(line);
47
+ }
48
+ });
49
+ });
50
+ child.stderr?.on('data', (data) => {
51
+ stderr += data.toString();
52
+ });
53
+ child.on('close', (code) => {
54
+ clearTimeout(timeoutId);
55
+ // Clean up temp file
56
+ try {
57
+ fs.unlinkSync(runnerPath);
58
+ }
59
+ catch { }
60
+ const duration = Date.now() - startTime;
61
+ if (timedOut) {
62
+ resolve({
63
+ success: false,
64
+ duration,
65
+ error: {
66
+ message: `Execution timed out after ${timeout}ms`,
67
+ code: 'TIMEOUT'
68
+ },
69
+ logs,
70
+ timestamp: new Date().toISOString()
71
+ });
72
+ return;
73
+ }
74
+ // Parse the result from stdout
75
+ const resultMatch = stdout.match(/__AFH_RESULT__:(.+)$/m);
76
+ if (resultMatch) {
77
+ try {
78
+ const result = JSON.parse(resultMatch[1]);
79
+ resolve({
80
+ success: result.success !== false,
81
+ duration,
82
+ output: result.output || result,
83
+ error: result.error,
84
+ logs,
85
+ timestamp: new Date().toISOString()
86
+ });
87
+ return;
88
+ }
89
+ catch (e) {
90
+ // Fall through to error handling
91
+ }
92
+ }
93
+ if (code !== 0 || stderr) {
94
+ resolve({
95
+ success: false,
96
+ duration,
97
+ error: {
98
+ message: stderr || `Process exited with code ${code}`,
99
+ code: code?.toString()
100
+ },
101
+ logs,
102
+ timestamp: new Date().toISOString()
103
+ });
104
+ return;
105
+ }
106
+ resolve({
107
+ success: true,
108
+ duration,
109
+ output: { raw: stdout },
110
+ logs,
111
+ timestamp: new Date().toISOString()
112
+ });
113
+ });
114
+ child.on('error', (err) => {
115
+ clearTimeout(timeoutId);
116
+ resolve({
117
+ success: false,
118
+ duration: Date.now() - startTime,
119
+ error: {
120
+ message: err.message,
121
+ stack: err.stack
122
+ },
123
+ logs,
124
+ timestamp: new Date().toISOString()
125
+ });
126
+ });
127
+ });
128
+ }
129
+ /**
130
+ * Generate a runner script that executes the handler
131
+ */
132
+ function generateRunnerScript(projectDir, options) {
133
+ const srcPath = path.join(projectDir, 'src', 'index.ts');
134
+ // Use forward slashes for imports even on Windows
135
+ const importPath = srcPath.replace(/\\/g, '/');
136
+ return `
137
+ // Auto-generated runner script for AFH dev server
138
+ import handler from '${importPath}';
139
+
140
+ const testValues = JSON.parse(process.env.AFH_TEST_VALUES || '{}');
141
+ const inputs = JSON.parse(process.env.AFH_INPUTS || '{}');
142
+
143
+ // Mock CheckpointManager for stateful handlers
144
+ class MockCheckpointManager {
145
+ private data: any = null;
146
+
147
+ async save(instanceId: string, data: any): Promise<void> {
148
+ this.data = { data, savedAt: Date.now(), instanceId };
149
+ console.log('[checkpoint:save]', JSON.stringify(data));
150
+ }
151
+
152
+ async load(jobId: string): Promise<any> {
153
+ return this.data;
154
+ }
155
+
156
+ async clear(jobId: string): Promise<void> {
157
+ this.data = null;
158
+ }
159
+ }
160
+
161
+ // Mock StatefulHandlerContext
162
+ function createMockContext() {
163
+ const checkpointManager = new MockCheckpointManager();
164
+
165
+ return {
166
+ // Base HandlerContext properties
167
+ executionId: 'dev-execution-' + Date.now(),
168
+ stepId: 'dev-step-1',
169
+ flowId: 'dev-flow',
170
+ attempt: 1,
171
+ maxAttempts: 3,
172
+ context: {},
173
+ vault: {
174
+ get: async (path: string) => {
175
+ console.log('[vault:get]', path);
176
+ return null;
177
+ }
178
+ },
179
+
180
+ // StatefulHandlerContext properties
181
+ checkpoints: checkpointManager,
182
+ instanceId: 'dev-instance-' + Date.now(),
183
+ jobId: 'dev-job-' + Date.now(),
184
+ isActive: async () => true,
185
+ updateProgress: async (percent: number, message?: string) => {
186
+ console.log('[progress]', percent + '%', message || '');
187
+ }
188
+ };
189
+ }
190
+
191
+ async function run() {
192
+ try {
193
+ const instance = handler as any;
194
+
195
+ // Inject mock _context for stateful handlers
196
+ // This is what the engine would normally do
197
+ instance._context = createMockContext();
198
+
199
+ // Apply test values first (as defaults)
200
+ for (const [key, value] of Object.entries(testValues)) {
201
+ if (key in instance) {
202
+ instance[key] = value;
203
+ }
204
+ }
205
+
206
+ // Apply inputs (override test values)
207
+ for (const [key, value] of Object.entries(inputs)) {
208
+ if (value !== undefined && value !== '') {
209
+ instance[key] = value;
210
+ }
211
+ }
212
+
213
+ // Execute the handler
214
+ const result = await instance.execute();
215
+
216
+ // Output the result in a parseable format
217
+ console.log('__AFH_RESULT__:' + JSON.stringify({
218
+ success: result?.outcome !== 'failure',
219
+ output: result?.output || result,
220
+ error: result?.outcome === 'failure' ? {
221
+ code: result.error?.code,
222
+ message: result.error?.message,
223
+ details: result.error?.details
224
+ } : undefined
225
+ }));
226
+
227
+ } catch (error) {
228
+ console.log('__AFH_RESULT__:' + JSON.stringify({
229
+ success: false,
230
+ error: {
231
+ code: 'EXECUTION_ERROR',
232
+ message: error instanceof Error ? error.message : String(error),
233
+ details: { stack: error instanceof Error ? error.stack : undefined }
234
+ }
235
+ }));
236
+ process.exit(1);
237
+ }
238
+ }
239
+
240
+ run();
241
+ `;
242
+ }
243
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/dev/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Extract @TestValue decorator values from handler source code
3
+ * This uses regex-based parsing for simplicity - a proper implementation
4
+ * would use TypeScript Compiler API
5
+ */
6
+ export declare function extractTestValuesFromSource(sourcePath: string): Record<string, any>;
7
+ /**
8
+ * Extract handler metadata from source
9
+ */
10
+ export declare function extractHandlerMetadata(sourcePath: string): Record<string, any>;
11
+ /**
12
+ * Extract @Input decorator metadata
13
+ */
14
+ export declare function extractInputMetadata(sourcePath: string): Record<string, Record<string, any>>;
15
+ //# sourceMappingURL=extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/dev/extractor.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CA4BnF;AAqED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAiC9E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAkG5F"}