@tbrandenburg/node-red-agents 0.1.3 → 0.1.4

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.
@@ -1,4 +1,4 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
3
  // Splits a string of gh CLI arguments into an argv array without any shell
4
4
  // evaluation. Single- and double-quoted spans are kept as one argument
@@ -11,57 +11,57 @@
11
11
  // 'list --label "needs review"' -> ['list', '--label', 'needs review']
12
12
  // 'pr list && rm -rf /' -> ['pr', 'list', '&&', 'rm', '-rf', '/']
13
13
  function parseArgs(str) {
14
- if (str === undefined || str === null) return [];
15
- if (typeof str !== 'string') {
16
- throw new Error('parseArgs: expected a string, got ' + typeof str);
17
- }
18
-
19
- const args = [];
20
- let current = '';
21
- let inArg = false;
22
- let quote = null; // '"' or "'" while inside a quoted span
23
-
24
- for (let i = 0; i < str.length; i += 1) {
25
- const ch = str[i];
14
+ if (str === undefined || str === null) return [];
15
+ if (typeof str !== "string") {
16
+ throw new Error("parseArgs: expected a string, got " + typeof str);
17
+ }
26
18
 
27
- if (quote) {
28
- if (ch === quote) {
29
- quote = null;
30
- } else {
31
- current += ch;
32
- }
33
- continue;
34
- }
19
+ const args = [];
20
+ let current = "";
21
+ let inArg = false;
22
+ let quote = null; // '"' or "'" while inside a quoted span
35
23
 
36
- if (ch === '"' || ch === "'") {
37
- quote = ch;
38
- inArg = true;
39
- continue;
40
- }
41
-
42
- if (ch === ' ' || ch === '\t' || ch === '\n' || ch === '\r') {
43
- if (inArg) {
44
- args.push(current);
45
- current = '';
46
- inArg = false;
47
- }
48
- continue;
49
- }
24
+ for (let i = 0; i < str.length; i += 1) {
25
+ const ch = str[i];
50
26
 
27
+ if (quote) {
28
+ if (ch === quote) {
29
+ quote = null;
30
+ } else {
51
31
  current += ch;
52
- inArg = true;
32
+ }
33
+ continue;
53
34
  }
54
35
 
55
- if (quote) {
56
- // Unterminated quote: fail safe by treating the rest of the
57
- // string as literal content rather than throwing, since this is
58
- // config text a user can fix, not something to crash a flow over.
59
- args.push(current);
60
- } else if (inArg) {
36
+ if (ch === '"' || ch === "'") {
37
+ quote = ch;
38
+ inArg = true;
39
+ continue;
40
+ }
41
+
42
+ if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r") {
43
+ if (inArg) {
61
44
  args.push(current);
45
+ current = "";
46
+ inArg = false;
47
+ }
48
+ continue;
62
49
  }
63
50
 
64
- return args;
51
+ current += ch;
52
+ inArg = true;
53
+ }
54
+
55
+ if (quote) {
56
+ // Unterminated quote: fail safe by treating the rest of the
57
+ // string as literal content rather than throwing, since this is
58
+ // config text a user can fix, not something to crash a flow over.
59
+ args.push(current);
60
+ } else if (inArg) {
61
+ args.push(current);
62
+ }
63
+
64
+ return args;
65
65
  }
66
66
 
67
67
  module.exports = { parseArgs };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tbrandenburg/node-red-agents",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Node-RED nodes for running coding agents (opencode, pi) and GitHub CLI operations from flows.",
5
5
  "keywords": [
6
6
  "node-red",
@@ -1,8 +1,8 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
- const fs = require('fs');
4
- const os = require('os');
5
- const path = require('path');
3
+ const fs = require("fs");
4
+ const os = require("os");
5
+ const path = require("path");
6
6
 
7
7
  // Translates the simple "Inline" SRT settings UI (two string lists + one
8
8
  // checkbox), used by both the `agent` and `agent-server` nodes, into the
@@ -25,18 +25,18 @@ const path = require('path');
25
25
  // "<field>: Required" for each one missing. This function always includes
26
26
  // all four.
27
27
  function buildSettingsJson({ allowedDomains, allowedWriteDirs, strictAllowlist } = {}) {
28
- return {
29
- network: {
30
- allowedDomains: Array.isArray(allowedDomains) ? allowedDomains : [],
31
- deniedDomains: [],
32
- strictAllowlist: strictAllowlist !== false
33
- },
34
- filesystem: {
35
- allowWrite: Array.isArray(allowedWriteDirs) ? allowedWriteDirs : [],
36
- denyRead: [],
37
- denyWrite: []
38
- }
39
- };
28
+ return {
29
+ network: {
30
+ allowedDomains: Array.isArray(allowedDomains) ? allowedDomains : [],
31
+ deniedDomains: [],
32
+ strictAllowlist: strictAllowlist !== false,
33
+ },
34
+ filesystem: {
35
+ allowWrite: Array.isArray(allowedWriteDirs) ? allowedWriteDirs : [],
36
+ denyRead: [],
37
+ denyWrite: [],
38
+ },
39
+ };
40
40
  }
41
41
 
42
42
  // config: { allowedDomains, allowedWriteDirs, strictAllowlist, advancedJson }
@@ -45,14 +45,17 @@ function buildSettingsJson({ allowedDomains, allowedWriteDirs, strictAllowlist }
45
45
  // writeInlineSettingsFile so tests can check the generated content without
46
46
  // needing a real filesystem.
47
47
  function resolveSettingsJsonString(config = {}) {
48
- const raw = config.advancedJson && config.advancedJson.trim() ? config.advancedJson : JSON.stringify(buildSettingsJson(config));
49
- // Throws a clear SyntaxError if the (usually hand-edited advanced) JSON
50
- // is invalid -- deliberately no deeper validation than "is this valid
51
- // JSON"; srt's own runtime error for a structurally-wrong-but-valid-JSON
52
- // settings file is already clear and surfaces through the normal
53
- // execution/spawn-failure path.
54
- JSON.parse(raw);
55
- return raw;
48
+ const raw =
49
+ config.advancedJson && config.advancedJson.trim()
50
+ ? config.advancedJson
51
+ : JSON.stringify(buildSettingsJson(config));
52
+ // Throws a clear SyntaxError if the (usually hand-edited advanced) JSON
53
+ // is invalid -- deliberately no deeper validation than "is this valid
54
+ // JSON"; srt's own runtime error for a structurally-wrong-but-valid-JSON
55
+ // settings file is already clear and surfaces through the normal
56
+ // execution/spawn-failure path.
57
+ JSON.parse(raw);
58
+ return raw;
56
59
  }
57
60
 
58
61
  // nodeId is used only to make the temp filename recognizable/stable per
@@ -61,11 +64,11 @@ function resolveSettingsJsonString(config = {}) {
61
64
  // filePrefix distinguishes callers (e.g. 'agent' vs 'agent-server') so two
62
65
  // different node types configuring the same nodeId-shaped id can never
63
66
  // collide on the same temp file.
64
- function writeInlineSettingsFile(nodeId, config, filePrefix = 'srt-settings') {
65
- const json = resolveSettingsJsonString(config);
66
- const filePath = path.join(os.tmpdir(), `${filePrefix}-${nodeId}-${process.pid}.json`);
67
- fs.writeFileSync(filePath, json);
68
- return filePath;
67
+ function writeInlineSettingsFile(nodeId, config, filePrefix = "srt-settings") {
68
+ const json = resolveSettingsJsonString(config);
69
+ const filePath = path.join(os.tmpdir(), `${filePrefix}-${nodeId}-${process.pid}.json`);
70
+ fs.writeFileSync(filePath, json);
71
+ return filePath;
69
72
  }
70
73
 
71
74
  module.exports = { buildSettingsJson, resolveSettingsJsonString, writeInlineSettingsFile };