@auxx/sdk 0.0.11 → 0.0.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 (51) hide show
  1. package/lib/api/api.js +2 -1
  2. package/lib/api/schemas.js +1 -0
  3. package/lib/build/server/find-tool-server-modules.js +279 -0
  4. package/lib/build/server/find-workflow-block-server-modules.js +10 -2
  5. package/lib/build/server/generate-server-entry.js +46 -1
  6. package/lib/build/server/zod-to-provider-tool-schema.js +42 -0
  7. package/lib/client/workflow/index.d.ts +1 -1
  8. package/lib/client/workflow/index.d.ts.map +1 -1
  9. package/lib/commands/dev/bundle-javascript.js +17 -1
  10. package/lib/commands/dev/prepare-build-context.js +11 -2
  11. package/lib/commands/dev/server-builder.js +2 -1
  12. package/lib/commands/dev/upload.js +5 -1
  13. package/lib/commands/dev.js +2 -1
  14. package/lib/commands/version/create/bundle-javascript.js +4 -0
  15. package/lib/commands/version/create.js +5 -1
  16. package/lib/env-loader.js +17 -1
  17. package/lib/root/app.d.ts +5 -2
  18. package/lib/root/app.d.ts.map +1 -1
  19. package/lib/root/index.d.ts +4 -2
  20. package/lib/root/index.d.ts.map +1 -1
  21. package/lib/root/index.js +2 -1
  22. package/lib/root/tools/define-tool.d.ts +4 -0
  23. package/lib/root/tools/define-tool.d.ts.map +1 -0
  24. package/lib/root/tools/define-tool.js +7 -0
  25. package/lib/root/tools/index.d.ts +5 -0
  26. package/lib/root/tools/index.d.ts.map +1 -0
  27. package/lib/root/tools/index.js +3 -0
  28. package/lib/root/tools/refs.d.ts +9 -0
  29. package/lib/root/tools/refs.d.ts.map +1 -0
  30. package/lib/root/tools/refs.js +4 -0
  31. package/lib/root/tools/types.d.ts +97 -0
  32. package/lib/root/tools/types.d.ts.map +1 -0
  33. package/lib/root/tools/types.js +1 -0
  34. package/lib/root/workflow/types.d.ts +27 -14
  35. package/lib/root/workflow/types.d.ts.map +1 -1
  36. package/lib/root/workflow/types.js +3 -0
  37. package/lib/root/workflow/utils.d.ts +4 -4
  38. package/lib/root/workflow/utils.d.ts.map +1 -1
  39. package/lib/runtime/workflow.js +17 -0
  40. package/lib/server/connections.d.ts +1 -0
  41. package/lib/server/connections.d.ts.map +1 -1
  42. package/lib/server/index.d.ts +1 -0
  43. package/lib/server/index.d.ts.map +1 -1
  44. package/lib/shared/errors.d.ts +4 -0
  45. package/lib/shared/errors.d.ts.map +1 -1
  46. package/lib/shared/errors.js +8 -0
  47. package/lib/shared/index.d.ts +1 -1
  48. package/lib/shared/index.d.ts.map +1 -1
  49. package/lib/shared/index.js +1 -1
  50. package/lib/util/compile-and-extract-catalog.js +279 -0
  51. package/package.json +5 -1
package/lib/api/api.js CHANGED
@@ -123,7 +123,7 @@ class ApiImpl {
123
123
  }
124
124
  return complete(result.value);
125
125
  }
126
- async createDeployment({ appId, clientBundleSha, serverBundleSha, deploymentType, settingsSchema, targetOrganizationId, environmentVariables, version, metadata, }) {
126
+ async createDeployment({ appId, clientBundleSha, serverBundleSha, deploymentType, settingsSchema, catalog, targetOrganizationId, environmentVariables, version, metadata, }) {
127
127
  const result = await this.fetcher.post({
128
128
  path: `/api/v1/apps/${appId}/deployments`,
129
129
  body: {
@@ -131,6 +131,7 @@ class ApiImpl {
131
131
  serverBundleSha,
132
132
  deploymentType,
133
133
  settingsSchema,
134
+ catalog,
134
135
  targetOrganizationId,
135
136
  environmentVariables,
136
137
  version,
@@ -38,6 +38,7 @@ const appDataSchema = z.object({
38
38
  avatarId: z.string().nullable().optional(),
39
39
  avatarUrl: z.string().nullable().optional(),
40
40
  category: z.string().nullable().optional(),
41
+ verified: z.boolean().optional(),
41
42
  createdAt: z.string().or(z.date()),
42
43
  updatedAt: z.string().or(z.date()),
43
44
  });
@@ -0,0 +1,279 @@
1
+ import fs from 'node:fs';
2
+ import { parse } from '@typescript-eslint/parser';
3
+ import { analyze } from '@typescript-eslint/scope-manager';
4
+ import { walk } from 'zimmerframe';
5
+ import { complete, errored } from '../../errors.js';
6
+ import { getAppEntryPoint } from '../../util/get-app-entry-point.js';
7
+ function checkPath(path, doesModuleExist) {
8
+ return doesModuleExist(path) ? path : null;
9
+ }
10
+ function resolvePathWithExtension(path, doesModuleExist) {
11
+ return (checkPath(path + '.ts', doesModuleExist) ||
12
+ checkPath(path + '.tsx', doesModuleExist) ||
13
+ checkPath(path + '.js', doesModuleExist));
14
+ }
15
+ function resolveAbsolutePath(sourcePath, currPath) {
16
+ if (sourcePath.startsWith('.')) {
17
+ const currDir = currPath.split('/').slice(0, -1).join('/');
18
+ const combinedPath = currDir + '/' + sourcePath;
19
+ const parts = combinedPath.split('/');
20
+ const resolvedParts = [];
21
+ for (const part of parts) {
22
+ if (part === '..') {
23
+ resolvedParts.pop();
24
+ }
25
+ else if (part !== '.') {
26
+ resolvedParts.push(part);
27
+ }
28
+ }
29
+ return resolvedParts.join('/');
30
+ }
31
+ return sourcePath;
32
+ }
33
+ function unwrapTypeAnnotations(node) {
34
+ while (node) {
35
+ if (node.type === 'TSSatisfiesExpression' || node.type === 'TSAsExpression') {
36
+ node = node.expression;
37
+ }
38
+ else if (node.type === 'TSTypeAssertion') {
39
+ node = node.expression;
40
+ }
41
+ else {
42
+ break;
43
+ }
44
+ }
45
+ return node;
46
+ }
47
+ function resolveIdentifierToValue(node, scope) {
48
+ const variable = scope.set.get(node.name);
49
+ if (!variable) {
50
+ throw new Error(`Unable to find variable ${node.name} in scope`);
51
+ }
52
+ if (variable.defs.length !== 1) {
53
+ throw new Error(`Expected exactly one definition for variable ${node.name}, found ${variable.defs.length}`);
54
+ }
55
+ const def = variable.defs[0];
56
+ if (!def)
57
+ return null;
58
+ if (def.node.type === 'VariableDeclarator')
59
+ return def.node.init;
60
+ if (def.type === 'ImportBinding')
61
+ return def;
62
+ return null;
63
+ }
64
+ function loadModule(sourcePath, currPath, helpers) {
65
+ const absolutePath = resolveAbsolutePath(sourcePath, currPath);
66
+ const fullPath = resolvePathWithExtension(absolutePath, helpers.doesModuleExist);
67
+ if (!fullPath) {
68
+ throw new Error(`Unable to resolve path for module ${sourcePath} from ${currPath}`);
69
+ }
70
+ if (helpers.modules.has(fullPath)) {
71
+ return helpers.modules.get(fullPath);
72
+ }
73
+ const content = helpers.getModuleSource(fullPath);
74
+ const ast = parse(content, { range: true, jsx: true });
75
+ const scopeManager = analyze(ast, { sourceType: 'module' });
76
+ const moduleScope = scopeManager.acquire(ast, true);
77
+ const namedExports = new Map();
78
+ const module = { content, ast, scope: moduleScope, namedExports, path: fullPath };
79
+ helpers.modules.set(fullPath, module);
80
+ walk(ast, null, {
81
+ ExportNamedDeclaration(node) {
82
+ if (node.declaration?.type === 'VariableDeclaration' &&
83
+ node.declaration.declarations.length === 1 &&
84
+ node.declaration.declarations[0].type === 'VariableDeclarator' &&
85
+ node.declaration.declarations[0].id.type === 'Identifier') {
86
+ const declaration = node.declaration.declarations[0];
87
+ namedExports.set(declaration.id.name, declaration.init);
88
+ }
89
+ if (node?.specifiers && moduleScope) {
90
+ for (const specifier of node.specifiers) {
91
+ if (specifier.type === 'ExportSpecifier' &&
92
+ specifier.exported.type === 'Identifier' &&
93
+ specifier.local.type === 'Identifier') {
94
+ if (node.source !== null) {
95
+ namedExports.set(specifier.exported.name, node);
96
+ }
97
+ else {
98
+ const resolved = resolveIdentifierToValue(specifier.local, moduleScope);
99
+ if (resolved)
100
+ namedExports.set(specifier.exported.name, resolved);
101
+ }
102
+ }
103
+ }
104
+ }
105
+ },
106
+ ExportDefaultDeclaration(node) {
107
+ if (node.declaration) {
108
+ if (node.declaration.type === 'FunctionDeclaration' ||
109
+ node.declaration.type === 'ArrowFunctionExpression' ||
110
+ node.declaration.type === 'FunctionExpression') {
111
+ namedExports.set('default', node.declaration);
112
+ }
113
+ else if (node.declaration.type === 'Identifier' && moduleScope) {
114
+ const resolved = resolveIdentifierToValue(node.declaration, moduleScope);
115
+ if (resolved)
116
+ namedExports.set('default', resolved);
117
+ }
118
+ }
119
+ },
120
+ });
121
+ return module;
122
+ }
123
+ function captureExecuteRef(toolId, node, scope, currPath, helpers) {
124
+ let importValue = node.type === 'Identifier' ? resolveIdentifierToValue(node, scope) : node;
125
+ if (!importValue) {
126
+ throw new Error(`Tool '${toolId}': unable to resolve 'execute'`);
127
+ }
128
+ importValue = unwrapTypeAnnotations(importValue);
129
+ const isInlineFunction = importValue.type === 'ArrowFunctionExpression' ||
130
+ importValue.type === 'FunctionExpression' ||
131
+ importValue.type === 'FunctionDeclaration';
132
+ if (isInlineFunction) {
133
+ throw new Error(`Tool '${toolId}': 'execute' must be imported from a separate .server.ts file. ` +
134
+ `Inline server functions are not allowed.`);
135
+ }
136
+ if (importValue.type !== 'ImportBinding' && importValue.type !== 'ExportNamedDeclaration') {
137
+ throw new Error(`Tool '${toolId}': 'execute' must be imported from another file. Found ${importValue.type}.`);
138
+ }
139
+ const importDeclaration = importValue.type === 'ExportNamedDeclaration' ? importValue : importValue.parent;
140
+ const sourcePath = importDeclaration.source.value;
141
+ const isServerFile = sourcePath.endsWith('.server') ||
142
+ sourcePath.endsWith('.server.ts') ||
143
+ sourcePath.endsWith('.server.tsx') ||
144
+ sourcePath.endsWith('.server.js');
145
+ if (!isServerFile) {
146
+ throw new Error(`Tool '${toolId}': 'execute' must be imported from a .server.ts file (got '${sourcePath}').`);
147
+ }
148
+ if (importValue.type === 'ImportBinding') {
149
+ const specifier = importDeclaration.specifiers.find((s) => s.local && s.local.name === importValue.name.name);
150
+ if (specifier && specifier.type !== 'ImportDefaultSpecifier') {
151
+ throw new Error(`Tool '${toolId}': 'execute' must be imported as a default export from '${sourcePath}'.`);
152
+ }
153
+ }
154
+ let absolutePath = resolveAbsolutePath(sourcePath, currPath);
155
+ absolutePath = resolvePathWithExtension(absolutePath, helpers.doesModuleExist) || absolutePath;
156
+ return { path: absolutePath, export: 'default' };
157
+ }
158
+ function visitTool(node, scope, result, currPath, helpers) {
159
+ if (node.type === 'Identifier') {
160
+ let targetScope = scope;
161
+ let value = resolveIdentifierToValue(node, scope);
162
+ let targetPath = currPath;
163
+ if (value?.type === 'ImportBinding') {
164
+ const importDeclaration = value.parent;
165
+ const module = loadModule(importDeclaration.source.value, currPath, helpers);
166
+ const local = value.name.name;
167
+ const specifier = importDeclaration.specifiers.find((s) => s.local && s.local.name === local);
168
+ const name = specifier?.imported?.name ?? 'default';
169
+ if (!module.namedExports.has(name)) {
170
+ throw new Error(`Unable to find named export ${name} in module ${importDeclaration.source.value}`);
171
+ }
172
+ value = module.namedExports.get(name) ?? null;
173
+ if (module.scope)
174
+ targetScope = module.scope;
175
+ targetPath = module.path;
176
+ }
177
+ value = value ? unwrapTypeAnnotations(value) : null;
178
+ if (!value) {
179
+ throw new Error(`Tool ${node.name}: expected initializer`);
180
+ }
181
+ if (value.type === 'CallExpression') {
182
+ visitTool(value.arguments[0], targetScope, result, targetPath, helpers);
183
+ return;
184
+ }
185
+ if (value.type !== 'ObjectExpression') {
186
+ throw new Error(`Tool ${node.name}: expected ObjectExpression, got ${value.type}`);
187
+ }
188
+ visitTool(value, targetScope, result, targetPath, helpers);
189
+ return;
190
+ }
191
+ if (node.type === 'CallExpression') {
192
+ visitTool(node.arguments[0], scope, result, currPath, helpers);
193
+ return;
194
+ }
195
+ if (node.type === 'ObjectExpression') {
196
+ let id;
197
+ let execute = null;
198
+ for (const property of node.properties) {
199
+ if (property.type !== 'Property' || property.key.type !== 'Identifier')
200
+ continue;
201
+ const name = property.key.name;
202
+ if (name === 'id') {
203
+ if (property.value.type !== 'Literal' || typeof property.value.value !== 'string') {
204
+ throw new Error(`Tool: 'id' must be a string literal`);
205
+ }
206
+ id = property.value.value;
207
+ }
208
+ else if (name === 'execute') {
209
+ execute = captureExecuteRef(id ?? '<unknown>', property.value, scope, currPath, helpers);
210
+ }
211
+ }
212
+ if (!id)
213
+ throw new Error(`Tool: missing 'id'`);
214
+ if (!execute)
215
+ throw new Error(`Tool '${id}': missing 'execute'`);
216
+ result.set(id, { execute });
217
+ }
218
+ }
219
+ function findProperty(obj, name, scope) {
220
+ const property = obj.properties.find((p) => p.type === 'Property' && p.key.type === 'Identifier' && p.key.name === name);
221
+ if (!property)
222
+ return null;
223
+ let value = property.value;
224
+ if (value.type === 'Identifier') {
225
+ const resolvedValue = resolveIdentifierToValue(value, scope);
226
+ if (resolvedValue && resolvedValue.type !== 'ImportBinding')
227
+ value = resolvedValue;
228
+ }
229
+ return value;
230
+ }
231
+ export function findToolModulesFromSource(source, currPath, helpers) {
232
+ const result = new Map();
233
+ try {
234
+ const ast = parse(source, { range: true, jsx: true });
235
+ const scopeManager = analyze(ast, { sourceType: 'module' });
236
+ const moduleScope = scopeManager.acquire(ast, true);
237
+ if (moduleScope === null) {
238
+ throw new Error('Expected to be able to acquire module scope');
239
+ }
240
+ ;
241
+ walk(ast, null, {
242
+ ExportNamedDeclaration(node) {
243
+ if (!node.declaration || node.declaration.type !== 'VariableDeclaration')
244
+ return;
245
+ if (node.declaration.declarations.length !== 1)
246
+ return;
247
+ const declaration = node.declaration.declarations[0];
248
+ if (declaration.id.type !== 'Identifier' || declaration.id.name !== 'app')
249
+ return;
250
+ const appValue = declaration.init;
251
+ if (!appValue || appValue.type !== 'ObjectExpression')
252
+ return;
253
+ const tools = findProperty(appValue, 'tools', moduleScope);
254
+ if (tools?.type !== 'ArrayExpression')
255
+ return;
256
+ for (const element of tools.elements) {
257
+ if (element)
258
+ visitTool(element, moduleScope, result, currPath, helpers);
259
+ }
260
+ },
261
+ });
262
+ }
263
+ catch (error) {
264
+ const message = error instanceof Error ? error.message : String(error);
265
+ return errored({ code: 'TOOL_RESOLUTION_FAILED', message });
266
+ }
267
+ return complete(result);
268
+ }
269
+ export async function findToolModules(srcDirAbsolute) {
270
+ const appEntryPoint = await getAppEntryPoint(srcDirAbsolute);
271
+ if (!appEntryPoint) {
272
+ return complete(new Map());
273
+ }
274
+ return findToolModulesFromSource(appEntryPoint.content, appEntryPoint.path, {
275
+ getModuleSource: (p) => fs.readFileSync(p, 'utf-8'),
276
+ doesModuleExist: (p) => fs.existsSync(p),
277
+ modules: new Map(),
278
+ });
279
+ }
@@ -240,12 +240,20 @@ function visitBlock(node, scope, result, currPath, helpers) {
240
240
  targetPath = module.path;
241
241
  }
242
242
  value = unwrapTypeAnnotations(value);
243
+ if (value?.type === 'CallExpression') {
244
+ visitBlock(value.arguments[0], targetScope, result, targetPath, helpers);
245
+ return;
246
+ }
243
247
  if (!value || value.type !== 'ObjectExpression') {
244
248
  throw new Error(`Expected variable ${node.name} to have an initializer`);
245
249
  }
246
250
  visitBlock(value, targetScope, result, targetPath, helpers);
247
251
  return;
248
252
  }
253
+ if (node.type === 'CallExpression') {
254
+ visitBlock(node.arguments[0], scope, result, currPath, helpers);
255
+ return;
256
+ }
249
257
  if (node.type === 'ObjectExpression') {
250
258
  let id;
251
259
  let execute;
@@ -381,12 +389,12 @@ export function findWorkflowBlockModulesFromSource(source, currPath, helpers) {
381
389
  const message = error instanceof Error ? error.message : String(error);
382
390
  return errored({ code: 'WORKFLOW_BLOCK_RESOLUTION_FAILED', message });
383
391
  }
384
- return complete(result);
392
+ return complete({ blocks: result });
385
393
  }
386
394
  export async function findWorkflowBlockModules(srcDirAbsolute) {
387
395
  const appEntryPoint = await getAppEntryPoint(srcDirAbsolute);
388
396
  if (!appEntryPoint) {
389
- return complete(new Map());
397
+ return complete({ blocks: new Map() });
390
398
  }
391
399
  const getModuleSource = (path) => {
392
400
  return fs.readFileSync(path, 'utf-8');
@@ -16,7 +16,7 @@ async function findServerFunctionModules(cwd, pattern) {
16
16
  });
17
17
  }
18
18
  }
19
- export async function generateServerEntry({ appDirAbsolute, srcDirAbsolute, webhooksDirAbsolute, eventDirAbsolute, workflowBlockModules, log, }) {
19
+ export async function generateServerEntry({ appDirAbsolute, srcDirAbsolute, webhooksDirAbsolute, eventDirAbsolute, workflowBlockModules, toolModules = new Map(), log, }) {
20
20
  const pathsResult = await combineAsync({
21
21
  serverFunctionConcretePaths: findServerFunctionModules(srcDirAbsolute, 'server'),
22
22
  webhookConcretePaths: findServerFunctionModules(webhooksDirAbsolute, 'webhook'),
@@ -105,6 +105,51 @@ export async function generateServerEntry({ appDirAbsolute, srcDirAbsolute, webh
105
105
  };
106
106
  }
107
107
 
108
+ // Tool module registry
109
+ const toolModulesMap = new Map()
110
+
111
+ ${[...toolModules.entries()]
112
+ .map(([toolId, handlers]) => `toolModulesMap.set(
113
+ ${JSON.stringify(toolId)},
114
+ {
115
+ ${[...Object.entries(handlers)]
116
+ .map(([handler, data]) => data
117
+ ? `${JSON.stringify(handler)}: {
118
+ module: () => import(${JSON.stringify(path.join(appDirAbsolute, data.path))}),
119
+ export: ${JSON.stringify(data.export)}
120
+ },`
121
+ : '')
122
+ .join('\n')}
123
+ }
124
+ )`)
125
+ .join('\n')}
126
+
127
+ // Build __AUXX_TOOLS__ — the single tool registry read by the unified
128
+ // lambda tool-executor for both agent-surfaced and action-surfaced
129
+ // invocations. Mirrors __AUXX_WORKFLOW_BLOCKS__: the executor reads
130
+ // execute(input, ctx) off this global. See plans/kopilot/agents/triggers/app-surface-implementation-plan.md §5.2.
131
+ const __AUXX_TOOLS__ = {};
132
+
133
+ for (const [toolId, handlers] of toolModulesMap.entries()) {
134
+ __AUXX_TOOLS__[toolId] = {
135
+ execute: async (...args) => {
136
+ const executeHandler = handlers.execute;
137
+ if (!executeHandler) {
138
+ throw new Error(\`No execute handler for tool \${toolId}\`);
139
+ }
140
+ const module = await executeHandler.module();
141
+ const func = module[executeHandler.export];
142
+ if (!func) {
143
+ throw new Error(\`Execute export not found in tool \${toolId}\`);
144
+ }
145
+ if (typeof func !== "function") {
146
+ throw new Error(\`Execute export in tool \${toolId} is not a function\`);
147
+ }
148
+ return await func(...args);
149
+ }
150
+ };
151
+ }
152
+
108
153
  var stdin_default;
109
154
  var stdin_webhooks_default;
110
155
  var stdin_events_default;
@@ -0,0 +1,42 @@
1
+ import { z } from 'zod/v4';
2
+ export function zodToProviderToolSchema(schema, _provider = 'anthropic') {
3
+ const raw = z.toJSONSchema(schema, { unrepresentable: 'any' });
4
+ delete raw.$schema;
5
+ delete raw.id;
6
+ const refs = [];
7
+ const cleaned = stripAuxxRefAndMineRefs(raw, [], refs);
8
+ return { jsonSchema: cleaned, refs };
9
+ }
10
+ function stripAuxxRefAndMineRefs(node, path, out) {
11
+ if (!node || typeof node !== 'object')
12
+ return node;
13
+ if (Array.isArray(node)) {
14
+ return node.map((entry, i) => stripAuxxRefAndMineRefs(entry, [...path, String(i)], out));
15
+ }
16
+ const obj = { ...node };
17
+ if (obj.auxxRef && typeof obj.auxxRef === 'object') {
18
+ const kind = obj.auxxRef.kind;
19
+ if (typeof kind === 'string') {
20
+ out.push({ path: [...path], kind });
21
+ }
22
+ delete obj.auxxRef;
23
+ }
24
+ if (obj.properties && typeof obj.properties === 'object') {
25
+ const props = obj.properties;
26
+ const cleanedProps = {};
27
+ for (const key of Object.keys(props)) {
28
+ cleanedProps[key] = stripAuxxRefAndMineRefs(props[key], [...path, key], out);
29
+ }
30
+ obj.properties = cleanedProps;
31
+ }
32
+ if (obj.items) {
33
+ obj.items = stripAuxxRefAndMineRefs(obj.items, [...path, '[]'], out);
34
+ }
35
+ if (obj.anyOf) {
36
+ obj.anyOf = obj.anyOf.map((entry) => stripAuxxRefAndMineRefs(entry, path, out));
37
+ }
38
+ if (obj.oneOf) {
39
+ obj.oneOf = obj.oneOf.map((entry) => stripAuxxRefAndMineRefs(entry, path, out));
40
+ }
41
+ return obj;
42
+ }
@@ -1,4 +1,4 @@
1
- export type { BaseType, Connection, InferWorkflowInput, InferWorkflowOutput, WorkflowBlock, WorkflowCategory, WorkflowExecutionContext, WorkflowOrganization, WorkflowSchema, WorkflowSDK, WorkflowTrigger, WorkflowUser, } from '../../root/workflow/types.js';
1
+ export type { BaseType, Connection, InferWorkflowInput, InferWorkflowOutput, Trigger, WorkflowBlock, WorkflowCategory, WorkflowExecutionContext, WorkflowOrganization, WorkflowSchema, WorkflowSDK, WorkflowUser, } from '../../root/workflow/types.js';
2
2
  export * from './components/index.js';
3
3
  export * from './hooks/index.js';
4
4
  export type { PathTo, PathToField, ValueAtPath } from './types/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/workflow/index.ts"],"names":[],"mappings":"AASA,YAAY,EACV,QAAQ,EACR,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,cAAc,EACd,WAAW,EACX,eAAe,EACf,YAAY,GACb,MAAM,8BAA8B,CAAA;AAGrC,cAAc,uBAAuB,CAAA;AAErC,cAAc,kBAAkB,CAAA;AAEhC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/workflow/index.ts"],"names":[],"mappings":"AASA,YAAY,EACV,QAAQ,EACR,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,cAAc,EACd,WAAW,EACX,YAAY,GACb,MAAM,8BAA8B,CAAA;AAGrC,cAAc,uBAAuB,CAAA;AAErC,cAAc,kBAAkB,CAAA;AAEhC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA"}
@@ -1,5 +1,7 @@
1
+ import chalk from 'chalk';
1
2
  import chokidar from 'chokidar';
2
3
  import { complete, isComplete, isErrored } from '../../errors.js';
4
+ import { compileAndExtractCatalog, } from '../../util/compile-and-extract-catalog.js';
3
5
  import { compileAndExtractSettingsSchema } from '../../util/compile-and-extract-settings.js';
4
6
  import { prepareBuildContext } from './prepare-build-context.js';
5
7
  export function bundleJavaScript(onSuccess, onError) {
@@ -39,7 +41,21 @@ export function bundleJavaScript(onSuccess, onError) {
39
41
  }
40
42
  const results = bundleResults.value;
41
43
  const settingsSchema = await compileAndExtractSettingsSchema();
42
- await onSuccess?.([results.client.outputFiles[0].text, results.server.outputFiles[0].text], settingsSchema);
44
+ const catalogResult = await compileAndExtractCatalog();
45
+ let catalog;
46
+ if (isErrored(catalogResult)) {
47
+ const err = catalogResult.error;
48
+ const detail = 'error' in err && err.error instanceof Error
49
+ ? `\n ${err.error.message}`
50
+ : 'message' in err
51
+ ? `\n ${err.message}`
52
+ : '';
53
+ process.stderr.write(chalk.yellow(`⚠ Catalog extraction failed (${err.code}) — deployment will ship with no catalog${detail}\n`));
54
+ }
55
+ else {
56
+ catalog = catalogResult.value;
57
+ }
58
+ await onSuccess?.([results.client.outputFiles[0].text, results.server.outputFiles[0].text], settingsSchema, catalog);
43
59
  isBuilding = false;
44
60
  if (buildQueued && !isDisposing) {
45
61
  buildQueued = false;
@@ -1,5 +1,6 @@
1
1
  import chalk from 'chalk';
2
2
  import path from 'path';
3
+ import { findToolModules } from '../../build/server/find-tool-server-modules.js';
3
4
  import { findWorkflowBlockModules } from '../../build/server/find-workflow-block-server-modules.js';
4
5
  import { combine, combineAsync, complete, isComplete, isErrored, map, } from '../../errors.js';
5
6
  import { ClientBuilder } from './client-builder.js';
@@ -41,10 +42,15 @@ export async function prepareBuildContext(mode) {
41
42
  if (isErrored(workflowBlockModulesResult)) {
42
43
  return workflowBlockModulesResult;
43
44
  }
44
- const workflowBlockModules = workflowBlockModulesResult.value;
45
+ const toolModulesResult = await findToolModules(srcDir);
46
+ if (isErrored(toolModulesResult)) {
47
+ return toolModulesResult;
48
+ }
49
+ const { blocks: workflowBlockModules } = workflowBlockModulesResult.value;
50
+ const toolModules = toolModulesResult.value;
45
51
  return combineAsync({
46
52
  client: client.rebuild({ workflowBlockModules }),
47
- server: server.rebuild({ workflowBlockModules }),
53
+ server: server.rebuild({ workflowBlockModules, toolModules }),
48
54
  });
49
55
  },
50
56
  dispose: async (timeoutMs) => {
@@ -86,5 +92,8 @@ export function printBuildContextError(error) {
86
92
  case 'WORKFLOW_BLOCK_RESOLUTION_FAILED':
87
93
  process.stderr.write(`${chalk.red('✖ ')}Failed to build workflow block(s): ${error.message}\n`);
88
94
  break;
95
+ case 'TOOL_RESOLUTION_FAILED':
96
+ process.stderr.write(`${chalk.red('✖ ')}Failed to resolve tool(s): ${error.message}\n`);
97
+ break;
89
98
  }
90
99
  }
@@ -42,13 +42,14 @@ export class ServerBuilder {
42
42
  });
43
43
  }
44
44
  }
45
- async rebuild({ workflowBlockModules, }) {
45
+ async rebuild({ workflowBlockModules, toolModules, }) {
46
46
  const jsResult = await generateServerEntry({
47
47
  appDirAbsolute: path.resolve(this._directories.app),
48
48
  srcDirAbsolute: path.resolve(this._directories.src),
49
49
  webhooksDirAbsolute: path.resolve(this._directories.webhooks),
50
50
  eventDirAbsolute: path.resolve(this._directories.events),
51
51
  workflowBlockModules,
52
+ toolModules: toolModules ?? new Map(),
52
53
  log: console.log,
53
54
  });
54
55
  if (isErrored(jsResult)) {
@@ -5,7 +5,7 @@ import { combineAsync, complete, isErrored } from '../../errors.js';
5
5
  import { calculateBundleSha } from '../../util/calculate-bundle-sha.js';
6
6
  import { spinnerify } from '../../util/spinner.js';
7
7
  import { uploadBundle } from '../../util/upload-bundle.js';
8
- export async function upload({ contents, appId, targetOrganizationId, environmentVariables, cliVersion, settingsSchema, }) {
8
+ export async function upload({ contents, appId, targetOrganizationId, environmentVariables, cliVersion, settingsSchema, catalog, }) {
9
9
  return await spinnerify('Uploading...', () => `Upload complete at ${new Date().toLocaleTimeString()}`, async () => {
10
10
  const [clientBundle, serverBundle] = contents;
11
11
  const clientSha = calculateBundleSha(clientBundle);
@@ -34,6 +34,9 @@ export async function upload({ contents, appId, targetOrganizationId, environmen
34
34
  if (settingsSchema) {
35
35
  process.stdout.write(`${chalk.green('✓ ')}Settings schema included\n`);
36
36
  }
37
+ if (catalog && (catalog.tools.length || catalog.toolsets.length)) {
38
+ process.stdout.write(`${chalk.green('✓ ')}Catalog extracted (${catalog.tools.length} tools, ${catalog.toolsets.length} toolsets, ${catalog.workflow.blocks.length} blocks, ${catalog.triggers.length} triggers, ${catalog.actions.length} actions)\n`);
39
+ }
37
40
  const deployResult = await api.createDeployment({
38
41
  appId,
39
42
  clientBundleSha: clientSha,
@@ -42,6 +45,7 @@ export async function upload({ contents, appId, targetOrganizationId, environmen
42
45
  targetOrganizationId,
43
46
  environmentVariables,
44
47
  settingsSchema,
48
+ catalog,
45
49
  metadata: { cliVersion },
46
50
  });
47
51
  if (isErrored(deployResult)) {
@@ -129,7 +129,7 @@ export const dev = new Command('dev')
129
129
  });
130
130
  cleanupFunctions.push(cleanupTs);
131
131
  let haveBundlingErrors = false;
132
- const cleanupJs = bundleJavaScript(async (contents, settingsSchema) => {
132
+ const cleanupJs = bundleJavaScript(async (contents, settingsSchema, catalog) => {
133
133
  if (haveBundlingErrors) {
134
134
  process.stdout.write(`${chalk.green('✓')} Bundling errors fixed\n`);
135
135
  haveBundlingErrors = false;
@@ -141,6 +141,7 @@ export const dev = new Command('dev')
141
141
  environmentVariables,
142
142
  cliVersion,
143
143
  settingsSchema,
144
+ catalog,
144
145
  });
145
146
  if (isErrored(uploadResult)) {
146
147
  printUploadError(uploadResult);
@@ -1,4 +1,5 @@
1
1
  import { complete, errored, isErrored } from '../../../errors.js';
2
+ import { compileAndExtractCatalog, } from '../../../util/compile-and-extract-catalog.js';
2
3
  import { compileAndExtractSettingsSchema } from '../../../util/compile-and-extract-settings.js';
3
4
  import { prepareBuildContext } from '../../dev/prepare-build-context.js';
4
5
  export async function bundleJavaScript() {
@@ -26,8 +27,11 @@ export async function bundleJavaScript() {
26
27
  });
27
28
  }
28
29
  const settingsSchema = await compileAndExtractSettingsSchema();
30
+ const catalogResult = await compileAndExtractCatalog();
31
+ const catalog = isErrored(catalogResult) ? undefined : catalogResult.value;
29
32
  return complete({
30
33
  bundles: [builds.client.outputFiles[0].text, builds.server.outputFiles[0].text],
31
34
  settingsSchema,
35
+ catalog,
32
36
  });
33
37
  }
@@ -64,11 +64,14 @@ export const versionCreate = new Command('create')
64
64
  }
65
65
  process.exit(1);
66
66
  }
67
- const { bundles, settingsSchema } = bundleResult.value;
67
+ const { bundles, settingsSchema, catalog } = bundleResult.value;
68
68
  const [clientBundle, serverBundle] = bundles;
69
69
  if (settingsSchema) {
70
70
  process.stdout.write(`${chalk.green('✓ ')}Settings schema extracted\n`);
71
71
  }
72
+ if (catalog && (catalog.tools.length || catalog.toolsets.length)) {
73
+ process.stdout.write(`${chalk.green('✓ ')}Catalog extracted (${catalog.tools.length} tools, ${catalog.toolsets.length} toolsets, ${catalog.workflow.blocks.length} blocks, ${catalog.triggers.length} triggers, ${catalog.actions.length} actions)\n`);
74
+ }
72
75
  const deployResult = await spinnerify('Uploading...', 'Upload complete', async () => {
73
76
  const cliVersionResult = loadAuxxCliVersion();
74
77
  if (isErrored(cliVersionResult)) {
@@ -112,6 +115,7 @@ export const versionCreate = new Command('create')
112
115
  serverBundleSha: serverSha,
113
116
  deploymentType: 'production',
114
117
  settingsSchema,
118
+ catalog,
115
119
  metadata: { cliVersion },
116
120
  });
117
121
  if (isErrored(result)) {
package/lib/env-loader.js CHANGED
@@ -1,2 +1,18 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { dirname, join, resolve } from 'node:path';
1
3
  import dotenv from 'dotenv';
2
- dotenv.config();
4
+ function findEnvFile() {
5
+ let dir = resolve(process.cwd());
6
+ const root = dirname(dir) === dir ? dir : '/';
7
+ while (true) {
8
+ const candidate = join(dir, '.env');
9
+ if (existsSync(candidate))
10
+ return candidate;
11
+ const parent = dirname(dir);
12
+ if (parent === dir || dir === root)
13
+ break;
14
+ dir = parent;
15
+ }
16
+ return undefined;
17
+ }
18
+ dotenv.config({ path: findEnvFile() });