@adminide-stack/form-builder-core 5.1.4-alpha.62 → 5.1.4-alpha.81
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/CHANGELOG.md +8 -0
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/inngest/monacoAutocompleteIntegration.d.ts +48 -0
- package/lib/inngest/monacoAutocompleteIntegration.d.ts.map +1 -0
- package/lib/inngest/monacoAutocompleteIntegration.js +341 -0
- package/lib/inngest/monacoAutocompleteIntegration.js.map +1 -0
- package/lib/inngest/stepGenerator.d.ts +41 -0
- package/lib/inngest/stepGenerator.d.ts.map +1 -1
- package/lib/inngest/stepGenerator.js +139 -1
- package/lib/inngest/stepGenerator.js.map +1 -1
- package/lib/utils/json.d.ts +3 -0
- package/lib/utils/json.d.ts.map +1 -0
- package/lib/utils/json.js +43 -0
- package/lib/utils/json.js.map +1 -0
- package/package.json +2 -2
- package/src/index.ts +3 -1
- package/src/inngest/MONACO_INTEGRATION_EXAMPLE.md +406 -0
- package/src/inngest/README_AUTOCOMPLETE.md +380 -0
- package/src/inngest/monacoAutocompleteIntegration.ts +432 -0
- package/src/inngest/stepGenerator.ts +183 -0
- package/src/utils/json.ts +50 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
function flatten(obj, parentKey = '', res = {}) {
|
|
2
|
+
Object.entries(obj).forEach(([key, value]) => {
|
|
3
|
+
const newKey = parentKey ? `${parentKey}.${key}` : key;
|
|
4
|
+
if (Array.isArray(value)) {
|
|
5
|
+
value.forEach((item, index) => {
|
|
6
|
+
if (item !== null && typeof item === 'object') {
|
|
7
|
+
flatten(item, `${newKey}.${index}`, res);
|
|
8
|
+
} else {
|
|
9
|
+
res[`${newKey}.${index}`] = item;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
} else if (value !== null && typeof value === 'object') {
|
|
13
|
+
flatten(value, newKey, res);
|
|
14
|
+
} else {
|
|
15
|
+
res[newKey] = value;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return res;
|
|
19
|
+
}
|
|
20
|
+
function unflatten(obj) {
|
|
21
|
+
const result = {};
|
|
22
|
+
if (!obj || typeof obj !== 'object') return result;
|
|
23
|
+
for (const [flatKey, value] of Object.entries(obj)) {
|
|
24
|
+
const keys = flatKey.split('.');
|
|
25
|
+
keys.reduce((acc, cur, i) => {
|
|
26
|
+
const isLast = i === keys.length - 1;
|
|
27
|
+
const nextKey = keys[i + 1];
|
|
28
|
+
const curIsIndex = !Number.isNaN(Number(cur));
|
|
29
|
+
const nextIsIndex = !Number.isNaN(Number(nextKey));
|
|
30
|
+
// If current key is numeric, treat parent as an array
|
|
31
|
+
if (curIsIndex) {
|
|
32
|
+
if (!Array.isArray(acc)) return [];
|
|
33
|
+
}
|
|
34
|
+
if (isLast) {
|
|
35
|
+
acc[cur] = value;
|
|
36
|
+
} else if (acc[cur] == null) {
|
|
37
|
+
acc[cur] = nextIsIndex ? [] : {};
|
|
38
|
+
}
|
|
39
|
+
return acc[cur];
|
|
40
|
+
}, result);
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}export{flatten,unflatten};//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sources":["../../src/utils/json.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA,SAAA,OAAA,CAAgB,GAAA,EAAA,cAAmB,EAAC,GAAA,GAAM,EAAE,EAAA;AAsB5C,EAAA,MAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,OAAgB,CAAA,CAAA,CAAA,GAAU,EAAG,KAAE,CAAA,KAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adminide-stack/form-builder-core",
|
|
3
|
-
"version": "5.1.4-alpha.
|
|
3
|
+
"version": "5.1.4-alpha.81",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -24,5 +24,5 @@
|
|
|
24
24
|
"publishConfig": {
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "883372f3751305aa9c87265af7b7b75ac9eee30e"
|
|
28
28
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export * from './inngest/interfaces/types';
|
|
2
2
|
export * from './inngest/generateFunctionCode';
|
|
3
|
-
export { generateFromExtractedFunctions } from './inngest/stepGenerator';
|
|
3
|
+
export { generateFromExtractedFunctions, extractFunctionBody } from './inngest/stepGenerator';
|
|
4
|
+
export * from './inngest/monacoAutocompleteIntegration';
|
|
5
|
+
export * from './utils/json';
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# Monaco Autocomplete Integration Example
|
|
2
|
+
|
|
3
|
+
This guide shows how to integrate the JavaScript autocomplete extension with your CodeEditor component using the command service pattern.
|
|
4
|
+
|
|
5
|
+
## Integration in CodeEditor Component
|
|
6
|
+
|
|
7
|
+
Here's how to update your `CodeEditor.tsx` to use the autocomplete extension:
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import Editor from '@monaco-editor/react';
|
|
12
|
+
import {
|
|
13
|
+
setupMonacoAutocomplete,
|
|
14
|
+
setupStepAutocomplete,
|
|
15
|
+
} from '@form-builder/core/inngest/monacoAutocompleteIntegration';
|
|
16
|
+
import { EditorSettings } from '../../types/inngest';
|
|
17
|
+
|
|
18
|
+
interface CodeEditorProps {
|
|
19
|
+
value: string;
|
|
20
|
+
onChange: (value: string | undefined) => void;
|
|
21
|
+
language?: string;
|
|
22
|
+
settings: EditorSettings;
|
|
23
|
+
height?: string;
|
|
24
|
+
readOnly?: boolean;
|
|
25
|
+
step?: any; // Current Inngest step being edited
|
|
26
|
+
services?: any; // Service container with command service
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const CodeEditor: React.FC<CodeEditorProps> = ({
|
|
30
|
+
value,
|
|
31
|
+
onChange,
|
|
32
|
+
language = 'typescript',
|
|
33
|
+
settings,
|
|
34
|
+
height = '400px',
|
|
35
|
+
readOnly = false,
|
|
36
|
+
step,
|
|
37
|
+
services,
|
|
38
|
+
}) => {
|
|
39
|
+
const handleEditorWillMount = async (monaco: any) => {
|
|
40
|
+
// 🆕 Setup autocomplete using the extension
|
|
41
|
+
if (services?.commands) {
|
|
42
|
+
if (step) {
|
|
43
|
+
// Setup step-specific autocomplete
|
|
44
|
+
await setupStepAutocomplete(monaco, step, value, services.commands);
|
|
45
|
+
} else {
|
|
46
|
+
// Setup general JavaScript autocomplete
|
|
47
|
+
await setupMonacoAutocomplete(
|
|
48
|
+
monaco,
|
|
49
|
+
{
|
|
50
|
+
enableInngestContext: true,
|
|
51
|
+
customScope: ['step', 'event'],
|
|
52
|
+
enableHoverInfo: true,
|
|
53
|
+
commandService: services.commands,
|
|
54
|
+
},
|
|
55
|
+
services.commands,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Add cdeops API type definitions
|
|
61
|
+
const cdeopsTypes = `
|
|
62
|
+
declare module 'cdeops/client' {
|
|
63
|
+
export interface ICodeJavascriptRequest {
|
|
64
|
+
script: string;
|
|
65
|
+
args: any[];
|
|
66
|
+
timeout?: number;
|
|
67
|
+
context?: Record<string, any>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export namespace code {
|
|
71
|
+
export namespace javascript {
|
|
72
|
+
export function executeScript(request: ICodeJavascriptRequest): Promise<any>;
|
|
73
|
+
export function getCompletions(context: { text: string; position: number; scope?: string[] }): Promise<any>;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
`;
|
|
78
|
+
|
|
79
|
+
monaco.languages.typescript.typescriptDefaults.addExtraLib(cdeopsTypes, 'file:///cdeops-types.d.ts');
|
|
80
|
+
|
|
81
|
+
// Add Inngest ambient types
|
|
82
|
+
const inngestAmbientTypes = `
|
|
83
|
+
declare const step: {
|
|
84
|
+
run<T>(id: string, fn: (event: any, step: any) => Promise<T> | T): Promise<T>;
|
|
85
|
+
sendEvent(id: string, input: { name: string; data?: any }): Promise<void>;
|
|
86
|
+
waitForEvent<T = any>(id: string, opts: { event: string; timeout?: string | number }): Promise<T>;
|
|
87
|
+
sleep(id: string, ms: string | number): Promise<void>;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
declare const event: { data: any };
|
|
91
|
+
`;
|
|
92
|
+
|
|
93
|
+
monaco.languages.typescript.typescriptDefaults.addExtraLib(
|
|
94
|
+
inngestAmbientTypes,
|
|
95
|
+
'file:///inngest-ambient-types.d.ts',
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// Configure TypeScript compiler options
|
|
99
|
+
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
|
|
100
|
+
target: monaco.languages.typescript.ScriptTarget.ES2020,
|
|
101
|
+
allowNonTSExtensions: true,
|
|
102
|
+
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
|
|
103
|
+
module: monaco.languages.typescript.ModuleKind.CommonJS,
|
|
104
|
+
noEmit: true,
|
|
105
|
+
esModuleInterop: true,
|
|
106
|
+
jsx: monaco.languages.typescript.JsxEmit.React,
|
|
107
|
+
reactNamespace: 'React',
|
|
108
|
+
allowJs: true,
|
|
109
|
+
typeRoots: ['node_modules/@types'],
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const editorOptions = {
|
|
114
|
+
fontSize: settings.fontSize,
|
|
115
|
+
tabSize: settings.tabSize,
|
|
116
|
+
wordWrap: settings.wordWrap ? ('on' as 'on') : ('off' as 'off'),
|
|
117
|
+
minimap: { enabled: false },
|
|
118
|
+
scrollBeyondLastLine: false,
|
|
119
|
+
automaticLayout: true,
|
|
120
|
+
formatOnPaste: true,
|
|
121
|
+
formatOnType: true,
|
|
122
|
+
readOnly,
|
|
123
|
+
suggest: {
|
|
124
|
+
showWords: false,
|
|
125
|
+
showSnippets: true,
|
|
126
|
+
preview: true, // Show completion preview
|
|
127
|
+
showIcons: true, // Show icons for completions
|
|
128
|
+
},
|
|
129
|
+
quickSuggestions: {
|
|
130
|
+
other: true,
|
|
131
|
+
comments: false,
|
|
132
|
+
strings: false,
|
|
133
|
+
},
|
|
134
|
+
hover: {
|
|
135
|
+
enabled: true, // Enable hover info
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const handleEditorDidMount = (_editor: any, monaco: any) => {
|
|
140
|
+
// Your existing Inngest snippets still work alongside autocomplete!
|
|
141
|
+
monaco.languages.registerCompletionItemProvider('typescript', {
|
|
142
|
+
provideCompletionItems: () => {
|
|
143
|
+
const suggestions = [
|
|
144
|
+
{
|
|
145
|
+
label: 'step.run',
|
|
146
|
+
kind: monaco.languages.CompletionItemKind.Snippet,
|
|
147
|
+
insertText: [
|
|
148
|
+
"const ${1:result} = await step.run('${2:step-id}', async (event, step) => {",
|
|
149
|
+
' ${3:// your logic}',
|
|
150
|
+
' return ${4:{ success: true }};',
|
|
151
|
+
'});',
|
|
152
|
+
].join('\n'),
|
|
153
|
+
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
|
154
|
+
documentation: 'Run a unit of work inside an Workflow step',
|
|
155
|
+
},
|
|
156
|
+
// ... other snippets
|
|
157
|
+
];
|
|
158
|
+
|
|
159
|
+
return { suggestions };
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<Editor
|
|
166
|
+
height={height}
|
|
167
|
+
language={language}
|
|
168
|
+
value={value}
|
|
169
|
+
onChange={onChange}
|
|
170
|
+
theme={settings.theme}
|
|
171
|
+
options={editorOptions}
|
|
172
|
+
beforeMount={handleEditorWillMount}
|
|
173
|
+
onMount={handleEditorDidMount}
|
|
174
|
+
/>
|
|
175
|
+
);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export default CodeEditor;
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Using in InngestEditor Component
|
|
182
|
+
|
|
183
|
+
Here's how to pass the services to your CodeEditor:
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
import React, { useContext } from 'react';
|
|
187
|
+
import CodeEditor from './CodeEditor';
|
|
188
|
+
import { ServiceContext } from '../../context/ServiceContext'; // Your service context
|
|
189
|
+
|
|
190
|
+
const InngestEditor: React.FC = () => {
|
|
191
|
+
const services = useContext(ServiceContext); // Get services from context
|
|
192
|
+
const [code, setCode] = React.useState('');
|
|
193
|
+
const [currentStep, setCurrentStep] = React.useState(null);
|
|
194
|
+
|
|
195
|
+
return (
|
|
196
|
+
<div>
|
|
197
|
+
<CodeEditor
|
|
198
|
+
value={code}
|
|
199
|
+
onChange={setCode}
|
|
200
|
+
language="typescript"
|
|
201
|
+
settings={editorSettings}
|
|
202
|
+
step={currentStep}
|
|
203
|
+
services={services} // Pass services including commands
|
|
204
|
+
/>
|
|
205
|
+
</div>
|
|
206
|
+
);
|
|
207
|
+
};
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Calling Extension Commands
|
|
211
|
+
|
|
212
|
+
The integration uses your existing command pattern:
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
// Example: Get completions
|
|
216
|
+
const result = await services.commands.executeCommand({
|
|
217
|
+
command: 'jsAutocomplete.getCompletions',
|
|
218
|
+
arguments: [text, position, scope],
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Example: Get type info
|
|
222
|
+
const typeInfo = await services.commands.executeCommand({
|
|
223
|
+
command: 'jsAutocomplete.getTypeInfo',
|
|
224
|
+
arguments: ['functionName', ['step', 'event']],
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Example: Install a library
|
|
228
|
+
await services.commands.executeCommand({
|
|
229
|
+
command: 'jsAutocomplete.installLibrary',
|
|
230
|
+
arguments: ['https://cdn.jsdelivr.net/npm/@types/lodash/index.d.ts', ['_', 'lodash']],
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Example: Update config
|
|
234
|
+
await services.commands.executeCommand({
|
|
235
|
+
command: 'jsAutocomplete.updateConfig',
|
|
236
|
+
arguments: [
|
|
237
|
+
{
|
|
238
|
+
includeDefaults: true,
|
|
239
|
+
includeLibraries: true,
|
|
240
|
+
customDefinitions: ['lodash', 'moment'],
|
|
241
|
+
},
|
|
242
|
+
],
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Available Extension Commands
|
|
247
|
+
|
|
248
|
+
### `jsAutocomplete.getCompletions`
|
|
249
|
+
|
|
250
|
+
Get code completions at a specific position.
|
|
251
|
+
|
|
252
|
+
**Arguments:** `[text: string, position: number, scope?: string[]]`
|
|
253
|
+
|
|
254
|
+
**Returns:**
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
{
|
|
258
|
+
completions: Array<{
|
|
259
|
+
name: string;
|
|
260
|
+
type?: string;
|
|
261
|
+
doc?: string;
|
|
262
|
+
url?: string;
|
|
263
|
+
}>;
|
|
264
|
+
isIncomplete: boolean;
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### `jsAutocomplete.getTypeInfo`
|
|
269
|
+
|
|
270
|
+
Get type information for a symbol.
|
|
271
|
+
|
|
272
|
+
**Arguments:** `[symbol: string, scope?: string[]]`
|
|
273
|
+
|
|
274
|
+
**Returns:**
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
{
|
|
278
|
+
type?: string;
|
|
279
|
+
doc?: string;
|
|
280
|
+
url?: string;
|
|
281
|
+
} | null
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### `jsAutocomplete.installLibrary`
|
|
285
|
+
|
|
286
|
+
Install a library for autocomplete.
|
|
287
|
+
|
|
288
|
+
**Arguments:** `[url: string, accessors: string[]]`
|
|
289
|
+
|
|
290
|
+
**Returns:** `boolean`
|
|
291
|
+
|
|
292
|
+
### `jsAutocomplete.uninstallLibrary`
|
|
293
|
+
|
|
294
|
+
Uninstall a library.
|
|
295
|
+
|
|
296
|
+
**Arguments:** `[accessors: string[]]`
|
|
297
|
+
|
|
298
|
+
**Returns:** `{ success: boolean; error?: string }`
|
|
299
|
+
|
|
300
|
+
### `jsAutocomplete.updateConfig`
|
|
301
|
+
|
|
302
|
+
Update autocomplete configuration.
|
|
303
|
+
|
|
304
|
+
**Arguments:** `[config: Partial<AutocompleteConfig>]`
|
|
305
|
+
|
|
306
|
+
**Returns:** `boolean`
|
|
307
|
+
|
|
308
|
+
### `jsAutocomplete.getAvailableDefinitions`
|
|
309
|
+
|
|
310
|
+
Get list of available type definitions.
|
|
311
|
+
|
|
312
|
+
**Arguments:** `[]`
|
|
313
|
+
|
|
314
|
+
**Returns:** `string[]`
|
|
315
|
+
|
|
316
|
+
### `jsAutocomplete.resetContext`
|
|
317
|
+
|
|
318
|
+
Reset the JavaScript execution context.
|
|
319
|
+
|
|
320
|
+
**Arguments:** `[]`
|
|
321
|
+
|
|
322
|
+
**Returns:** `boolean`
|
|
323
|
+
|
|
324
|
+
## Helper Functions
|
|
325
|
+
|
|
326
|
+
The `monacoAutocompleteIntegration.ts` provides helper functions:
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
import {
|
|
330
|
+
setupMonacoAutocomplete,
|
|
331
|
+
setupStepAutocomplete,
|
|
332
|
+
installLibraryForAutocomplete,
|
|
333
|
+
updateAutocompleteConfig,
|
|
334
|
+
getAvailableDefinitions,
|
|
335
|
+
} from '@form-builder/core/inngest/monacoAutocompleteIntegration';
|
|
336
|
+
|
|
337
|
+
// Setup general autocomplete
|
|
338
|
+
await setupMonacoAutocomplete(monaco, options, commandService);
|
|
339
|
+
|
|
340
|
+
// Setup step-specific autocomplete
|
|
341
|
+
await setupStepAutocomplete(monaco, step, code, commandService);
|
|
342
|
+
|
|
343
|
+
// Install a library
|
|
344
|
+
await installLibraryForAutocomplete(commandService, 'https://cdn.jsdelivr.net/npm/@types/lodash/index.d.ts', [
|
|
345
|
+
'_',
|
|
346
|
+
'lodash',
|
|
347
|
+
]);
|
|
348
|
+
|
|
349
|
+
// Update config
|
|
350
|
+
await updateAutocompleteConfig(commandService, {
|
|
351
|
+
includeDefaults: true,
|
|
352
|
+
includeLibraries: true,
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Get available definitions
|
|
356
|
+
const defs = await getAvailableDefinitions(commandService);
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## Testing the Integration
|
|
360
|
+
|
|
361
|
+
1. **Start your application** with the js-autocomplete-extension installed
|
|
362
|
+
2. **Open a step editor** with a code block
|
|
363
|
+
3. **Type `step.`** - You should see intelligent completions with type info
|
|
364
|
+
4. **Hover over `step`** - You should see type information
|
|
365
|
+
5. **Type any JavaScript** - Get ECMAScript completions
|
|
366
|
+
|
|
367
|
+
## Debugging
|
|
368
|
+
|
|
369
|
+
Check if the extension is working:
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
// In your component
|
|
373
|
+
React.useEffect(() => {
|
|
374
|
+
if (services?.commands) {
|
|
375
|
+
// Test if extension commands are available
|
|
376
|
+
services.commands
|
|
377
|
+
.executeCommand({
|
|
378
|
+
command: 'jsAutocomplete.getAvailableDefinitions',
|
|
379
|
+
arguments: [],
|
|
380
|
+
})
|
|
381
|
+
.then((defs) => {
|
|
382
|
+
console.log('Available definitions:', defs);
|
|
383
|
+
})
|
|
384
|
+
.catch((err) => {
|
|
385
|
+
console.error('Extension not available:', err);
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
}, [services]);
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Benefits
|
|
392
|
+
|
|
393
|
+
✅ **Context-aware completions** based on your step type
|
|
394
|
+
✅ **Type information** on hover
|
|
395
|
+
✅ **Library support** (lodash, moment, custom libs)
|
|
396
|
+
✅ **Dynamic updates** as you edit code
|
|
397
|
+
✅ **Inngest-specific** completions for step functions
|
|
398
|
+
✅ **Works alongside** your existing snippets
|
|
399
|
+
✅ **Uses your existing** command execution pattern
|
|
400
|
+
|
|
401
|
+
## Next Steps
|
|
402
|
+
|
|
403
|
+
- Add more step-specific completions
|
|
404
|
+
- Integrate with your workflow execution context
|
|
405
|
+
- Add custom library definitions for your domain
|
|
406
|
+
- Implement signature help for function parameters
|