n8n-nodes-cliclaw 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Ahmed El-Hadidi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # n8n-nodes-cliclaw
2
+
3
+ `n8n-nodes-cliclaw` provides two community nodes for n8n:
4
+
5
+ - `cliclaw`: connects to a remote host over SSH and runs `codex exec`
6
+ - `cliclaw SSH`: keeps a generic SSH node for command execution and file transfer
7
+
8
+ The main purpose of this package is to let n8n call Codex CLI on a remote machine where `codex` is already installed and authenticated.
9
+
10
+ ## Installation
11
+
12
+ ### Local installation
13
+
14
+ ```bash
15
+ npm install n8n-nodes-cliclaw
16
+ ```
17
+
18
+ ### n8n Community Nodes
19
+
20
+ 1. Open `Settings > Community Nodes`
21
+ 2. Select `Install`
22
+ 3. Enter `n8n-nodes-cliclaw`
23
+ 4. Confirm the installation
24
+
25
+ ## What `cliclaw` does
26
+
27
+ The `cliclaw` node wraps the Codex CLI command below over SSH:
28
+
29
+ ```bash
30
+ codex exec [options] "your prompt"
31
+ ```
32
+
33
+ It is designed for non-interactive automation. For remote workflows, this is the correct Codex CLI entry point instead of slash commands, because slash commands are intended for interactive sessions.
34
+
35
+ The node currently exposes these Codex CLI capabilities:
36
+
37
+ - `--cd`
38
+ - `--model`
39
+ - `--sandbox`
40
+ - `--ask-for-approval`
41
+ - `--json`
42
+ - `--image`
43
+ - `--output-last-message`
44
+ - extra raw arguments
45
+
46
+ ## Remote host prerequisites
47
+
48
+ The SSH target machine should already have:
49
+
50
+ 1. `codex` installed and available in `PATH`, or an absolute binary path you can provide
51
+ 2. valid Codex authentication on that host
52
+ 3. permission to access the remote working directory and any remote image paths you pass in
53
+
54
+ Each SSH credential now includes a `Remote OS` single-select field:
55
+
56
+ - `Linux`
57
+ - `macOS`
58
+ - `Windows`
59
+
60
+ The node uses this to wrap the remote command correctly before calling Codex CLI:
61
+
62
+ - Linux and macOS: `bash -lc 'export PATH="$HOME/.local/bin:$PATH" && codex exec ...'`
63
+ - Windows: `powershell -NoProfile -Command 'codex exec ...'`
64
+
65
+ ## Example
66
+
67
+ Use the `cliclaw` node with:
68
+
69
+ - `Host`: your remote server
70
+ - `Username`: your SSH user
71
+ - `Codex Binary`: `codex`
72
+ - `Remote Working Directory`: `/srv/project`
73
+ - `Prompt`: `Review the repo and fix the failing tests`
74
+ - `JSON Output`: enabled
75
+
76
+ The node returns:
77
+
78
+ - `stdout`
79
+ - `stderr`
80
+ - `exitCode`
81
+ - `success`
82
+ - `command`
83
+ - `parsedStdout` when stdout is valid JSON
84
+
85
+ ## Generic SSH node
86
+
87
+ `cliclaw SSH` is still available when you need plain SSH commands, uploads, or downloads outside Codex CLI usage.
88
+
89
+ ## Development
90
+
91
+ ```bash
92
+ pnpm install
93
+ pnpm build
94
+ pnpm lint
95
+ ```
96
+
97
+ ## References
98
+
99
+ - [Codex CLI reference](https://developers.openai.com/codex/cli/reference)
100
+ - [Codex CLI slash commands](https://developers.openai.com/codex/cli/slash-commands)
101
+ - [Codex CLI features](https://developers.openai.com/codex/cli/features#image-generation)
@@ -0,0 +1,8 @@
1
+ import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class ExampleCredentialsApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ properties: INodeProperties[];
6
+ authenticate: IAuthenticateGeneric;
7
+ test: ICredentialTestRequest;
8
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExampleCredentialsApi = void 0;
4
+ class ExampleCredentialsApi {
5
+ constructor() {
6
+ this.name = 'exampleCredentialsApi';
7
+ this.displayName = 'Example Credentials API';
8
+ this.properties = [
9
+ {
10
+ displayName: 'User Name',
11
+ name: 'username',
12
+ type: 'string',
13
+ default: '',
14
+ },
15
+ {
16
+ displayName: 'Password',
17
+ name: 'password',
18
+ type: 'string',
19
+ typeOptions: {
20
+ password: true,
21
+ },
22
+ default: '',
23
+ },
24
+ ];
25
+ this.authenticate = {
26
+ type: 'generic',
27
+ properties: {
28
+ auth: {
29
+ username: '={{ $credentials.username }}',
30
+ password: '={{ $credentials.password }}',
31
+ },
32
+ qs: {
33
+ n8n: 'rocks',
34
+ },
35
+ },
36
+ };
37
+ this.test = {
38
+ request: {
39
+ baseURL: 'https://example.com/',
40
+ url: '',
41
+ },
42
+ };
43
+ }
44
+ }
45
+ exports.ExampleCredentialsApi = ExampleCredentialsApi;
46
+ //# sourceMappingURL=ExampleCredentialsApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExampleCredentialsApi.credentials.js","sourceRoot":"","sources":["../../credentials/ExampleCredentialsApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,qBAAqB;IAAlC;QACC,SAAI,GAAG,uBAAuB,CAAC;QAC/B,gBAAW,GAAG,yBAAyB,CAAC;QACxC,eAAU,GAAsB;YAI/B;gBACC,WAAW,EAAE,WAAW;gBACxB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aACX;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACZ,QAAQ,EAAE,IAAI;iBACd;gBACD,OAAO,EAAE,EAAE;aACX;SACD,CAAC;QAKF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,IAAI,EAAE;oBACL,QAAQ,EAAE,8BAA8B;oBACxC,QAAQ,EAAE,8BAA8B;iBACxC;gBACD,EAAE,EAAE;oBAEH,GAAG,EAAE,OAAO;iBACZ;aACD;SACD,CAAC;QAGF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,sBAAsB;gBAC/B,GAAG,EAAE,EAAE;aACP;SACD,CAAC;IACH,CAAC;CAAA;AAhDD,sDAgDC"}
@@ -0,0 +1,7 @@
1
+ import type { ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class SshPasswordApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SshPasswordApi = void 0;
4
+ class SshPasswordApi {
5
+ constructor() {
6
+ this.name = 'sshPasswordApi';
7
+ this.displayName = 'SSH Password';
8
+ this.documentationUrl = 'https://docs.n8n.io/integrations/builtin/credentials/ssh/';
9
+ this.properties = [
10
+ {
11
+ displayName: 'Host',
12
+ name: 'host',
13
+ required: true,
14
+ type: 'string',
15
+ default: '',
16
+ placeholder: 'localhost',
17
+ },
18
+ {
19
+ displayName: 'Port',
20
+ name: 'port',
21
+ required: true,
22
+ type: 'number',
23
+ default: 22,
24
+ },
25
+ {
26
+ displayName: 'Username',
27
+ name: 'username',
28
+ type: 'string',
29
+ default: '',
30
+ },
31
+ {
32
+ displayName: 'Password',
33
+ name: 'password',
34
+ type: 'string',
35
+ typeOptions: {
36
+ password: true,
37
+ },
38
+ default: '',
39
+ },
40
+ {
41
+ displayName: 'Remote OS',
42
+ name: 'remoteOs',
43
+ type: 'options',
44
+ default: 'linux',
45
+ options: [
46
+ {
47
+ name: 'Linux',
48
+ value: 'linux',
49
+ },
50
+ {
51
+ name: 'macOS',
52
+ value: 'macos',
53
+ },
54
+ {
55
+ name: 'Windows',
56
+ value: 'windows',
57
+ },
58
+ ],
59
+ description: 'Operating system of the remote host so the node can preload the right shell command',
60
+ },
61
+ ];
62
+ }
63
+ }
64
+ exports.SshPasswordApi = SshPasswordApi;
65
+ //# sourceMappingURL=SshPasswordApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SshPasswordApi.credentials.js","sourceRoot":"","sources":["../../credentials/SshPasswordApi.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,cAAc;IAA3B;QACQ,SAAI,GAAG,gBAAgB,CAAC;QAExB,gBAAW,GAAG,cAAc,CAAC;QAE7B,qBAAgB,GAAG,2DAA2D,CAAC;QAE/E,eAAU,GAAsB;YACxB;gBACQ,WAAW,EAAE,MAAM;gBACnB,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,WAAW;aAC/B;YACD;gBACQ,WAAW,EAAE,MAAM;gBACnB,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aAClB;YACD;gBACQ,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aAClB;YACD;gBACQ,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACL,QAAQ,EAAE,IAAI;iBACrB;gBACD,OAAO,EAAE,EAAE;aAClB;YACD;gBACQ,WAAW,EAAE,WAAW;gBACxB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,OAAO;gBAChB,OAAO,EAAE;oBACD;wBACQ,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,OAAO;qBACrB;oBACD;wBACQ,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,OAAO;qBACrB;oBACD;wBACQ,IAAI,EAAE,SAAS;wBACf,KAAK,EAAE,SAAS;qBACvB;iBACR;gBACD,WAAW,EAAE,qFAAqF;aACzG;SACR,CAAC;IACV,CAAC;CAAA;AA5DD,wCA4DC"}
@@ -0,0 +1,7 @@
1
+ import type { ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class SshPrivateKeyApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SshPrivateKeyApi = void 0;
4
+ class SshPrivateKeyApi {
5
+ constructor() {
6
+ this.name = 'sshPrivateKeyApi';
7
+ this.displayName = 'SSH Private Key';
8
+ this.documentationUrl = 'https://docs.n8n.io/integrations/builtin/credentials/ssh/';
9
+ this.properties = [
10
+ {
11
+ displayName: 'Host',
12
+ name: 'host',
13
+ required: true,
14
+ type: 'string',
15
+ default: '',
16
+ placeholder: 'localhost',
17
+ },
18
+ {
19
+ displayName: 'Port',
20
+ name: 'port',
21
+ required: true,
22
+ type: 'number',
23
+ default: 22,
24
+ },
25
+ {
26
+ displayName: 'Username',
27
+ name: 'username',
28
+ type: 'string',
29
+ default: '',
30
+ },
31
+ {
32
+ displayName: 'Private Key',
33
+ name: 'privateKey',
34
+ type: 'string',
35
+ typeOptions: {
36
+ rows: 4,
37
+ password: true,
38
+ },
39
+ default: '',
40
+ },
41
+ {
42
+ displayName: 'Passphrase',
43
+ name: 'passphrase',
44
+ type: 'string',
45
+ default: '',
46
+ description: 'Passphase used to create the key, if no passphase was used leave empty',
47
+ typeOptions: { password: true },
48
+ },
49
+ {
50
+ displayName: 'Remote OS',
51
+ name: 'remoteOs',
52
+ type: 'options',
53
+ default: 'linux',
54
+ options: [
55
+ {
56
+ name: 'Linux',
57
+ value: 'linux',
58
+ },
59
+ {
60
+ name: 'macOS',
61
+ value: 'macos',
62
+ },
63
+ {
64
+ name: 'Windows',
65
+ value: 'windows',
66
+ },
67
+ ],
68
+ description: 'Operating system of the remote host so the node can preload the right shell command',
69
+ },
70
+ ];
71
+ }
72
+ }
73
+ exports.SshPrivateKeyApi = SshPrivateKeyApi;
74
+ //# sourceMappingURL=SshPrivateKeyApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SshPrivateKeyApi.credentials.js","sourceRoot":"","sources":["../../credentials/SshPrivateKeyApi.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,gBAAgB;IAA7B;QACQ,SAAI,GAAG,kBAAkB,CAAC;QAE1B,gBAAW,GAAG,iBAAiB,CAAC;QAEhC,qBAAgB,GAAG,2DAA2D,CAAC;QAE/E,eAAU,GAAsB;YACxB;gBACQ,WAAW,EAAE,MAAM;gBACnB,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,WAAW;aAC/B;YACD;gBACQ,WAAW,EAAE,MAAM;gBACnB,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aAClB;YACD;gBACQ,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aAClB;YACD;gBACQ,WAAW,EAAE,aAAa;gBAC1B,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACL,IAAI,EAAE,CAAC;oBACP,QAAQ,EAAE,IAAI;iBACrB;gBACD,OAAO,EAAE,EAAE;aAClB;YACD;gBACQ,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,wEAAwE;gBACrF,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;aACtC;YACD;gBACQ,WAAW,EAAE,WAAW;gBACxB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,OAAO;gBAChB,OAAO,EAAE;oBACD;wBACQ,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,OAAO;qBACrB;oBACD;wBACQ,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,OAAO;qBACrB;oBACD;wBACQ,IAAI,EAAE,SAAS;wBACf,KAAK,EAAE,SAAS;qBACvB;iBACR;gBACD,WAAW,EAAE,qFAAqF;aACzG;SACR,CAAC;IACV,CAAC;CAAA;AArED,4CAqEC"}
@@ -0,0 +1,12 @@
1
+ import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ interface IExtendedNodeTypeDescription extends INodeTypeDescription {
3
+ usableAsTool?: boolean;
4
+ }
5
+ export declare class Cliclaw implements INodeType {
6
+ description: IExtendedNodeTypeDescription;
7
+ methods: {
8
+ loadOptions: {};
9
+ };
10
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
11
+ }
12
+ export {};