@n8n/node-cli 0.22.0 → 0.23.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/dist/build.tsbuildinfo +1 -1
- package/dist/commands/release.d.ts +3 -1
- package/dist/commands/release.js +49 -3
- package/dist/commands/release.js.map +1 -1
- package/dist/template/core.js +1 -1
- package/dist/template/core.js.map +1 -1
- package/dist/template/templates/shared/default/.agents/credentials.md +115 -0
- package/dist/template/templates/shared/default/.agents/nodes-declarative.md +103 -0
- package/dist/template/templates/shared/default/.agents/nodes-programmatic.md +76 -0
- package/dist/template/templates/shared/default/.agents/nodes.md +178 -0
- package/dist/template/templates/shared/default/.agents/properties.md +174 -0
- package/dist/template/templates/shared/default/.agents/versioning.md +90 -0
- package/dist/template/templates/shared/default/.agents/workflow.md +97 -0
- package/dist/template/templates/shared/default/AGENTS.md +102 -0
- package/dist/template/templates/shared/default/CLAUDE.md +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Properties, expressions, and dynamic options
|
|
2
|
+
|
|
3
|
+
## Expressions
|
|
4
|
+
Parameter values can be expressions when they start with `=`. Everything
|
|
5
|
+
inside `{{ ... }}` is evaluated as JavaScript. Common (but not all)
|
|
6
|
+
special variables:
|
|
7
|
+
- `$value` - the value of the current parameter
|
|
8
|
+
- `$parameter` - object with all of the parameter values (key = name)
|
|
9
|
+
- `$credentials` - object with all of the credential values
|
|
10
|
+
|
|
11
|
+
## displayOptions
|
|
12
|
+
You can show or hide parameters based on other parameters using `displayOptions`:
|
|
13
|
+
```typescript
|
|
14
|
+
{
|
|
15
|
+
// ...
|
|
16
|
+
displayOptions: {
|
|
17
|
+
show: {
|
|
18
|
+
// show this parameter when parameter `inputMode` has value of `'json'`
|
|
19
|
+
inputMode: ['json'],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
Using condition:
|
|
25
|
+
```typescript
|
|
26
|
+
{
|
|
27
|
+
// ...
|
|
28
|
+
displayOptions: {
|
|
29
|
+
show: {
|
|
30
|
+
// show this parameter when parameter `inputMode` ends with `'json'`
|
|
31
|
+
inputMode: [{ _cnd: { endsWith: 'json' } }],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
Hide example:
|
|
37
|
+
```typescript
|
|
38
|
+
{
|
|
39
|
+
// ...
|
|
40
|
+
displayOptions: {
|
|
41
|
+
hide: {
|
|
42
|
+
// hide this parameter when `resource` is either `'user'` or `'organization'` and `operation` is `'getRepositories'`
|
|
43
|
+
resource: ['user', 'organization'],
|
|
44
|
+
operation: ['getRepositories'],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
You can also show/hide based on the node's version using `@version`:
|
|
50
|
+
```typescript
|
|
51
|
+
{
|
|
52
|
+
displayOptions: {
|
|
53
|
+
show: {
|
|
54
|
+
// only show for versions earlier than 1.4
|
|
55
|
+
'@version': [{ _cnd: { lt: 1.4 } }],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Loading dynamic options
|
|
62
|
+
Most properties are entirely defined in the code, but sometimes some
|
|
63
|
+
data needs to be fetched dynamically. For that case, you can use one of:
|
|
64
|
+
|
|
65
|
+
### loadOptionsMethod
|
|
66
|
+
For `options` / `multiOptions`:
|
|
67
|
+
```typescript
|
|
68
|
+
{
|
|
69
|
+
displayName: 'Category',
|
|
70
|
+
name: 'categoryId',
|
|
71
|
+
type: 'options',
|
|
72
|
+
typeOptions: {
|
|
73
|
+
loadOptionsMethod: 'getCategories',
|
|
74
|
+
},
|
|
75
|
+
default: '',
|
|
76
|
+
description: 'Choose a category',
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
Node class:
|
|
80
|
+
```typescript
|
|
81
|
+
methods = {
|
|
82
|
+
loadOptions: {
|
|
83
|
+
async getCategories(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
|
84
|
+
// Make an API call and return an array of { name, value }
|
|
85
|
+
return [];
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### resourceLocator
|
|
92
|
+
Used when the user can either choose from a list or specify an ID manually:
|
|
93
|
+
```typescript
|
|
94
|
+
{
|
|
95
|
+
displayName: 'Tool',
|
|
96
|
+
name: 'tool',
|
|
97
|
+
type: 'resourceLocator',
|
|
98
|
+
default: { mode: 'list', value: '' },
|
|
99
|
+
required: true,
|
|
100
|
+
description: 'The tool to use',
|
|
101
|
+
modes: [
|
|
102
|
+
{
|
|
103
|
+
displayName: 'From List',
|
|
104
|
+
name: 'list',
|
|
105
|
+
type: 'list',
|
|
106
|
+
typeOptions: {
|
|
107
|
+
searchListMethod: 'getTools',
|
|
108
|
+
searchable: true,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
displayName: 'ID',
|
|
113
|
+
name: 'id',
|
|
114
|
+
type: 'string',
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
Node class:
|
|
120
|
+
```typescript
|
|
121
|
+
methods = {
|
|
122
|
+
listSearch: {
|
|
123
|
+
async getTools(this: ILoadOptionsFunctions) {
|
|
124
|
+
// Return items suitable for a searchable list
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### resourceMapper
|
|
131
|
+
Use when the **schema is dynamic**, e.g. Google Sheets, where columns
|
|
132
|
+
can change:
|
|
133
|
+
```typescript
|
|
134
|
+
{
|
|
135
|
+
displayName: 'Parameters',
|
|
136
|
+
name: 'parameters',
|
|
137
|
+
type: 'resourceMapper',
|
|
138
|
+
default: {
|
|
139
|
+
mappingMode: 'defineBelow',
|
|
140
|
+
value: null,
|
|
141
|
+
},
|
|
142
|
+
noDataExpression: true,
|
|
143
|
+
required: true,
|
|
144
|
+
typeOptions: {
|
|
145
|
+
loadOptionsDependsOn: ['tool.value'],
|
|
146
|
+
resourceMapper: {
|
|
147
|
+
resourceMapperMethod: 'getToolParameters',
|
|
148
|
+
hideNoDataError: true,
|
|
149
|
+
addAllFields: false,
|
|
150
|
+
supportAutoMap: false,
|
|
151
|
+
mode: 'add',
|
|
152
|
+
fieldWords: {
|
|
153
|
+
singular: 'parameter',
|
|
154
|
+
plural: 'parameters',
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
displayOptions: {
|
|
159
|
+
show: {
|
|
160
|
+
inputMode: ['manual'],
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
Node class:
|
|
166
|
+
```typescript
|
|
167
|
+
export async function getToolParameters(
|
|
168
|
+
this: ILoadOptionsFunctions,
|
|
169
|
+
): Promise<ResourceMapperFields> {
|
|
170
|
+
// Implementation omitted; build fields based on the external tool
|
|
171
|
+
return { fields: [] };
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
Use `resourceMapper` **only when necessary**, as it is more advanced.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Versioning
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Nodes have versions, defined in the `version` property:
|
|
5
|
+
- If the node has only one version -> `version: 1`
|
|
6
|
+
- If the node supports **light versioning** -> `version: [1, 1.1, 1.2]`
|
|
7
|
+
etc.
|
|
8
|
+
|
|
9
|
+
Use versioning when you make **breaking changes** that should not alter
|
|
10
|
+
the behavior of existing workflows.
|
|
11
|
+
|
|
12
|
+
## Checking version in code
|
|
13
|
+
```typescript
|
|
14
|
+
async execute(this: IExecuteFunctions) {
|
|
15
|
+
const version = this.getNode().typeVersion;
|
|
16
|
+
if (version >= 1.1) {
|
|
17
|
+
// v1.1+ behavior
|
|
18
|
+
} else {
|
|
19
|
+
// v1 behavior
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Full versioning
|
|
25
|
+
For more complex changes, nodes can extend `VersionedNodeType`, where
|
|
26
|
+
each "full" version is a separate implementation. This is called **full
|
|
27
|
+
versioning** and is **only supported for programmatic-style nodes**:
|
|
28
|
+
```typescript
|
|
29
|
+
// If.node.ts
|
|
30
|
+
export class If extends VersionedNodeType {
|
|
31
|
+
constructor() {
|
|
32
|
+
const baseDescription: INodeTypeBaseDescription = {
|
|
33
|
+
displayName: 'If',
|
|
34
|
+
name: 'if',
|
|
35
|
+
icon: 'fa:map-signs',
|
|
36
|
+
iconColor: 'green',
|
|
37
|
+
group: ['transform'],
|
|
38
|
+
description: 'Route items to different branches (true/false)',
|
|
39
|
+
defaultVersion: 2.3,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const nodeVersions: IVersionedNodeType['nodeVersions'] = {
|
|
43
|
+
1: new IfV1(baseDescription),
|
|
44
|
+
2: new IfV2(baseDescription),
|
|
45
|
+
2.1: new IfV2(baseDescription),
|
|
46
|
+
2.2: new IfV2(baseDescription),
|
|
47
|
+
2.3: new IfV2(baseDescription),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
super(nodeVersions, baseDescription);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// IfV1.node.ts
|
|
55
|
+
export class IfV1 implements INodeType {
|
|
56
|
+
description: INodeTypeDescription;
|
|
57
|
+
|
|
58
|
+
constructor(baseDescription: INodeTypeBaseDescription) {
|
|
59
|
+
this.description = {
|
|
60
|
+
...baseDescription,
|
|
61
|
+
version: 1,
|
|
62
|
+
defaults: {
|
|
63
|
+
name: 'If',
|
|
64
|
+
color: '#408000',
|
|
65
|
+
},
|
|
66
|
+
inputs: [NodeConnectionTypes.Main],
|
|
67
|
+
outputs: [NodeConnectionTypes.Main, NodeConnectionTypes.Main],
|
|
68
|
+
outputNames: ['true', 'false'],
|
|
69
|
+
properties: [
|
|
70
|
+
// ...
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
|
76
|
+
// ...
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Important rules
|
|
82
|
+
- **Declarative-style nodes do not support full versioning**, only light
|
|
83
|
+
versioning
|
|
84
|
+
- Do **not** introduce full versioning unless:
|
|
85
|
+
- The node already uses it, or
|
|
86
|
+
- You are explicitly asked to add a new full version, or
|
|
87
|
+
- You're doing a complete **rewrite** of the node from scratch and it
|
|
88
|
+
has different resources/operations compared to last version
|
|
89
|
+
- **Do NOT** introduce full versioning when writing the very first
|
|
90
|
+
version of the node
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Workflow
|
|
2
|
+
|
|
3
|
+
## How to work on this project
|
|
4
|
+
When asked to build or update a node in this project, follow these steps:
|
|
5
|
+
|
|
6
|
+
1. Clarify the requirements. Ask for (if not already provided):
|
|
7
|
+
- Which resources and operations the node needs to have
|
|
8
|
+
- The authentication method (API key, OAuth2, etc)
|
|
9
|
+
- Example use case or sample payloads, if available
|
|
10
|
+
Do this **only** if there are multiple options **after** gathering
|
|
11
|
+
information and you are not sure which to pick
|
|
12
|
+
2. Decide on the node style (declarative vs programmatic):
|
|
13
|
+
- Prefer declarative-style nodes when:
|
|
14
|
+
- The integration is mostly simple HTTP/REST requests and responses
|
|
15
|
+
- You can express this behavior by mapping parameters to
|
|
16
|
+
URL/query/body/headers
|
|
17
|
+
- Use programmatic-style nodes only when you have at least one of:
|
|
18
|
+
- Multiple dependent API calls are needed per execution
|
|
19
|
+
- Complex control flow or aggregation
|
|
20
|
+
- Responses require heavy transformation that can't be described
|
|
21
|
+
declaratively
|
|
22
|
+
- If you choose programmatic-style, briefly explain **why**
|
|
23
|
+
declarative-style won't work for this particular node
|
|
24
|
+
3. Plan before coding:
|
|
25
|
+
- Outline what description the node will have, its resources and
|
|
26
|
+
operations
|
|
27
|
+
- Which credentials the node will use and their properties
|
|
28
|
+
- Confirm the plan, if you are not given one and are generating it
|
|
29
|
+
- **Never start coding without a plan**
|
|
30
|
+
4. Implement. Create or update:
|
|
31
|
+
- The node files (`nodes/<n>/<n>.node.ts`)
|
|
32
|
+
- The credentials files (`credentials/<n>.credentials.ts`)
|
|
33
|
+
- Other files with helpers and extracted functions/classes
|
|
34
|
+
- `package.json` (`n8n.nodes` and `n8n.credentials` entries)
|
|
35
|
+
5. Quality checks:
|
|
36
|
+
- Build the project to ensure it actually builds
|
|
37
|
+
- Run the linter to make sure that there aren't any warnings or
|
|
38
|
+
errors
|
|
39
|
+
- Ensure UX follows the [n8n UX guidelines](https://docs.n8n.io/integrations/creating-nodes/build/reference/ux-guidelines/)
|
|
40
|
+
- Ensure the credentials are secure (sensitive values **are marked as
|
|
41
|
+
`password`**, **no secrets logged** and **there aren't any
|
|
42
|
+
hardcoded secrets**)
|
|
43
|
+
- Run the project, so that the user can manually verify that it works.
|
|
44
|
+
Ask the user on how to run it, and if something goes wrong tell
|
|
45
|
+
them to run it themselves
|
|
46
|
+
6. Iterate on the code, if needed, going through the process again:
|
|
47
|
+
- Plan
|
|
48
|
+
- Implement
|
|
49
|
+
- Verify
|
|
50
|
+
|
|
51
|
+
## Development guidelines
|
|
52
|
+
- Use the `n8n-node` CLI tool **whenever possible**, so for stuff like building
|
|
53
|
+
a node, using dev mode with hot-reload linting, etc. Using this tool is the
|
|
54
|
+
best way to make sure the code is of high quality and complies with n8n's
|
|
55
|
+
standards
|
|
56
|
+
- **Always** make sure to address any lint/typecheck errors/warnings, unless
|
|
57
|
+
there is a **very specific reason** to ignore/disable it. Linter is your best
|
|
58
|
+
friend to make sure the code is of high quality and complies with n8n's
|
|
59
|
+
standards
|
|
60
|
+
- Before making any changes to the code, make sure you've gathered all required
|
|
61
|
+
context and **planned out** what you're going to do. If the plan looks good,
|
|
62
|
+
make sure to stick to it to ensure the code you produce is doing what the
|
|
63
|
+
user expects
|
|
64
|
+
- After making changes verify that there are no lint/typecheck issues. Also
|
|
65
|
+
allow the user to manually test the node in n8n to verify that it does what
|
|
66
|
+
is expected
|
|
67
|
+
- Make sure to use **proper types whenever possible**
|
|
68
|
+
- If you are updating the npm package version, make sure to **update
|
|
69
|
+
CHANGELOG.md** in the root of the repository
|
|
70
|
+
|
|
71
|
+
## CLI
|
|
72
|
+
This project uses n8n's CLI tool for developing community nodes: `n8n-node`. It
|
|
73
|
+
is available as a dev dependency and `package.json` has some aliases for common
|
|
74
|
+
commands. Short overview of the commands:
|
|
75
|
+
- `n8n-node dev` - run n8n with your node in development mode with hot reload.
|
|
76
|
+
This command starts up n8n on `http://localhost:5678` so that the user can
|
|
77
|
+
manually test the node. It also links it to n8n's custom nodes directory
|
|
78
|
+
(`~/.n8n-node-cli/.n8n/custom` by default), so it's available within n8n.
|
|
79
|
+
`--external-n8n` makes it not launch n8n and `--custom-user-folder <path>`
|
|
80
|
+
can be used to specify the folder where user-specific data is stored
|
|
81
|
+
(`~/.n8n-node-cli` is the default)
|
|
82
|
+
- `n8n-node build` - compile your node and prepare it for distribution.
|
|
83
|
+
- `n8n-node lint` - lint the node in the current directory.
|
|
84
|
+
Use `--fix` flag to automatically fix fixable issues.
|
|
85
|
+
- `n8n-node cloud-support` - manage n8n Cloud eligibility.
|
|
86
|
+
If invoked without arguments, show current cloud support status. Invoke
|
|
87
|
+
`n8n-node cloud-support enable` to enable strict mode + default ESLint config
|
|
88
|
+
or `n8n-node cloud-support disable` to allow custom ESLint config (disables
|
|
89
|
+
cloud eligibility)
|
|
90
|
+
- `n8n-node release` - publish your community node package to npm.
|
|
91
|
+
This command handles the complete release process using `release-it`:
|
|
92
|
+
- Builds the node
|
|
93
|
+
- Runs linting checks
|
|
94
|
+
- Updates changelog
|
|
95
|
+
- Creates git tags
|
|
96
|
+
- Creates GitHub releases
|
|
97
|
+
- Publishes to npm
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# n8n community node
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
This is a project containing code for an n8n community node. n8n is a workflow
|
|
5
|
+
automation platform where users build workflows with nodes, which are the
|
|
6
|
+
building block of a workflow. Nodes can perform a range of actions, such as
|
|
7
|
+
starting a workflow (called a "trigger node"), fetching and sending data, or
|
|
8
|
+
processing and manipulating it. Besides that there are credentials - entities
|
|
9
|
+
that store sensitive information on how to connect to external services and
|
|
10
|
+
APIs. A node can require some credentials to be used. Community nodes are a way
|
|
11
|
+
for anyone to create such nodes and add them to be used in n8n. All community
|
|
12
|
+
nodes are named in a format: `n8n-nodes-<n>` or `@org/n8n-nodes-<n>`.
|
|
13
|
+
Community nodes can also be submitted for approval to be used on n8n Cloud
|
|
14
|
+
version. In that case there are rules that the node needs to follow in order to
|
|
15
|
+
be approved
|
|
16
|
+
|
|
17
|
+
## Important notes
|
|
18
|
+
- Follow the **rules and guidelines in this document and the linked docs
|
|
19
|
+
below** over any code examples.
|
|
20
|
+
- All code blocks in these docs are **illustrative and incomplete**.
|
|
21
|
+
They **MUST NOT** be copied verbatim or assumed to be the final desired code.
|
|
22
|
+
- Replace example names like `Example`, `Wordpress`, `wordpressApi`, etc.
|
|
23
|
+
with names that match the **actual service / node** you are building.
|
|
24
|
+
- When in doubt, **generalize from the patterns**, don't replicate the exact
|
|
25
|
+
structure, fields, or values from the examples.
|
|
26
|
+
- Produce the **full implementation** needed for the current project
|
|
27
|
+
(nodes, credentials, tests, etc.), not just fragments similar to examples.
|
|
28
|
+
- If an example omits parts (e.g. types, operations, properties), **infer and
|
|
29
|
+
implement the missing parts** based on the real requirements / API docs.
|
|
30
|
+
- Never output `Wordpress`-specific code unless the project is actually about
|
|
31
|
+
WordPress.
|
|
32
|
+
|
|
33
|
+
## Project structure
|
|
34
|
+
There are two main folders in this project:
|
|
35
|
+
- `nodes` contains all of the nodes in a package (there can be more than 1).
|
|
36
|
+
The code for each node usually lives in its own folder
|
|
37
|
+
- `credentials` contains all of the credentials in a package. Usually it's just
|
|
38
|
+
a single file for every credential
|
|
39
|
+
So it looks something like this:
|
|
40
|
+
.
|
|
41
|
+
├── nodes/
|
|
42
|
+
│ └── Example/
|
|
43
|
+
│ ├── Example.node.ts
|
|
44
|
+
│ └── ...
|
|
45
|
+
├── credentials/
|
|
46
|
+
│ └── Example.credentials.ts
|
|
47
|
+
├── package.json
|
|
48
|
+
└── ...
|
|
49
|
+
It's important to note that `package.json` has a special field `n8n` that have
|
|
50
|
+
information about nodes and credentials in a package:
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"name": "n8n-nodes-example",
|
|
54
|
+
"version": "1.0.0",
|
|
55
|
+
"n8n": {
|
|
56
|
+
"n8nNodesApiVersion": 1,
|
|
57
|
+
"strict": true,
|
|
58
|
+
"credentials": [
|
|
59
|
+
"dist/credentials/Example.credentials.js"
|
|
60
|
+
],
|
|
61
|
+
"nodes": [
|
|
62
|
+
"dist/nodes/Example/Example.node.js"
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
`nodes` and `credentials` keys contain paths to transpiled JS files in a `dist`
|
|
68
|
+
folder for the nodes and credentials respectively. If you add/remove/rename
|
|
69
|
+
nodes and/or credentials, you need to make sure to update `n8n.nodes` and
|
|
70
|
+
`n8n.credentials` keys in `package.json` accordingly. Initial files in the
|
|
71
|
+
project _may_ contain example nodes and/or credentials that need to be
|
|
72
|
+
**removed or renamed** once you start making an actual node.
|
|
73
|
+
|
|
74
|
+
## Key guidelines
|
|
75
|
+
- Use the `n8n-node` CLI tool **whenever possible** for building, dev mode,
|
|
76
|
+
linting, etc.
|
|
77
|
+
- **Always** address any lint/typecheck errors/warnings, unless there is a
|
|
78
|
+
**very specific reason** to ignore/disable it
|
|
79
|
+
- Make sure to use **proper types whenever possible**
|
|
80
|
+
- If you are updating the npm package version, make sure to **update
|
|
81
|
+
CHANGELOG.md** in the root of the repository
|
|
82
|
+
- Read `.agents/workflow.md` for more info
|
|
83
|
+
|
|
84
|
+
## Context-specific docs
|
|
85
|
+
Load these before working on the relevant area:
|
|
86
|
+
|
|
87
|
+
| Working on... | Read first |
|
|
88
|
+
|--------------------------------------|---------------------------------------------------------------------|
|
|
89
|
+
| Any node file in `nodes/` | `.agents/nodes.md` and `.agents/properties.md` |
|
|
90
|
+
| A declarative-style node | above + `.agents/nodes-declarative.md` |
|
|
91
|
+
| A programmatic-style node | above + `.agents/nodes-programmatic.md` |
|
|
92
|
+
| Files in `credentials/` | `.agents/credentials.md` |
|
|
93
|
+
| Adding a new version to a node | `.agents/versioning.md` |
|
|
94
|
+
| Starting a new task or planning | `.agents/workflow.md` |
|
|
95
|
+
|
|
96
|
+
## Additional resources
|
|
97
|
+
If you need any extra information, here are links to n8n's official docs
|
|
98
|
+
regarding building community nodes:
|
|
99
|
+
- https://docs.n8n.io/integrations/community-nodes/build-community-nodes/
|
|
100
|
+
- https://docs.n8n.io/integrations/creating-nodes/overview/
|
|
101
|
+
- https://docs.n8n.io/integrations/creating-nodes/build/reference/
|
|
102
|
+
- https://docs.n8n.io/integrations/creating-nodes/build/reference/ux-guidelines/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@n8n/node-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.1",
|
|
4
4
|
"description": "Official CLI for developing community nodes for n8n",
|
|
5
5
|
"bin": {
|
|
6
6
|
"n8n-node": "bin/n8n-node.mjs"
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"files": [
|
|
15
15
|
"bin",
|
|
16
16
|
"dist",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
17
|
+
"LICENSE.md",
|
|
18
|
+
"LICENSE_EE.md"
|
|
19
19
|
],
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"rimraf": "6.0.1",
|
|
46
46
|
"ts-morph": "^27.0.2",
|
|
47
47
|
"typescript-eslint": "^8.35.0",
|
|
48
|
-
"@n8n/
|
|
49
|
-
"@n8n/
|
|
48
|
+
"@n8n/ai-node-sdk": "0.4.1",
|
|
49
|
+
"@n8n/eslint-plugin-community-nodes": "0.9.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@eslint/js": "^9.29.0",
|